3721研发网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > FPGA,CPLD和ASIC > Verilog实现关于24位输出的并串转换输出,附代码以及modelsim的仿真图。

Verilog实现关于24位输出的并串转换输出,附代码以及modelsim的仿真图。

时间:12-25 整理:3721RD 点击:
我的设计当中load是来加载输出24位数据的,只有前面24个时钟进行串并转换,后面的104个时钟保持输出为零。
我主要想问的就是为什么第一个load的高电平来到的时候,输出dout就变成未知了,要等到下一个load高电平的时候(再经过128个时钟周期)才进行并串转换。有没有什么办法可以在第一个load电平来临的时候就开始进行转换,我尝试了一下都没有成功。如果这么运行,是不是可以理解为,总体的输出被延迟了一个并行的输出时钟周期(48kHz)。(主时钟频率为6.144MHz)
还有就是,这个module是我的设计当中最后一个module,由于不知道怎么做时钟分频,才干脆用主时钟6.144MHz来驱动最后这个24位输出的并串转换(输出频率为48kHz),降采样了128倍。我是这么想的,48kHZ的并行数据要输出,那么串行数据的输出就应该是48kHZ*24=1152kHz,这就不能用偶次幂来实现分频,如果直接进行3/8分频那么好像jitter会比较大。所以才会出现前面24个时钟转换,后面为零的情况。我没有做过具体的电路,我想问一下,如果是真实的芯片这么处理问题大吗?
还有一个问题是真实的芯片最后的串行数据需要有串行开始结束的标志位吗?如果有一些标志位啊什么的,那我是不是可以用48kHz*32=1536kHz(主频的四分频)来进行并串转换。在32个时钟当中就会有24个是在进行并串转换,剩下的8个时钟就可以在前面、后面加上一些标志,等待,控制位了。这样行吗?
最后一个问题这样的代码最后能够综合布线吗?

这个是我的代码
module shifter(din,clk,reset,dout,load);
input [23:0]din;
input load;
input clk;
input reset;
outputdout;
reg [23:0] data_buf;

always @ (posedge load)
begin
data_buf <= din;
end

always@(posedge clk or posedge reset)
begin
if(reset == 1'b1)
data_buf<=24'b0;
else
begin

data_buf<=data_buf<<1;
end
end

assign dout=data_buf[23];

endmodule

`timescale 1ns/1ns
module t;
reg clk,reset;
reg [5:0] rptr;
regsigned [23:0] sindat[0:64];
integer file;
wire dout;
reg [23:0] din;
reg load;

initial
begin
$readmemb("shift.dat",sindat);
end
//export the waveform
initial
begin
file=$fopen("shift.txt","w");
end
always @(posedge clk)
begin
$fwrite(file,"%d\n",t.m.dout);
end
//The main block, generate the stimulus
always @(posedge load)
begin
rptr<=rptr + 1;
end
always @(posedge load)
begin
if (reset ==1'b1)
din <= 0;
else
din <= sindat[rptr];//the filter_in has 4-bit-width
end

initial
begin
rptr =0;
clk=1;
load=0;
reset=0;
#40 reset = 1;
#20 reset = 0;
#60 load= 1;
#20 load= 0;

#(127*40+20) load =1;
#20 load= 0;
#(127*40+20) load =1;
#20 load= 0;
#(127*40+20) load =1;
#20 load= 0;
#(20 * 1000) $stop;
end

always #(20) clk=~clk;


shifter m(.din(din),.dout(dout),.clk(clk),.load(load),.reset(reset));
endmodule

上面是testbench~

always @ (posedge load)
begin
data_buf <= din;
end
这个看起来就很别扭

我建议用个计数器吧,每次时钟沿一来,传一位出去,并且计数器加1.eg:
data_buf<=data_buf [NUM];
NUM <= NUM +1'b1;
if(NUM==5'd24) begin
NUM <= 5'd0;
end

学习,学习!

你的load信号出来时din没有准备好,当然每次采样都是上一次的数据了。

谢谢6楼,有个计数器是要好一些。现在想想其实要是用FSM可能更好控制一点吧

谢谢你的回复,那么我想请教一下需要怎么修改呢?

suiji
我想问一下,一般这种问题需要怎么修改的呢

很好
大家继续发扬

bucuo,zhengxuyao

Copyright © 2017-2020 3721研发网 版权所有

网站地图 鄂ICP备17025094号

Top