在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 7644|回复: 12

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

[复制链接]
发表于 2010-1-11 21:18:56 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
我的设计当中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个时钟就可以在前面、后面加上一些标志,等待,控制位了。这样行吗?

最后一个问题这样的代码最后能够综合布线吗?
wave1.JPG
wave2.JPG
 楼主| 发表于 2010-1-11 21:19:57 | 显示全部楼层
这个是我的代码

module shifter(din,clk,reset,dout,load);

input [23:0]din;
input load;
input clk;
input reset;

output  dout;

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
 楼主| 发表于 2010-1-11 21:20:58 | 显示全部楼层
`timescale 1ns/1ns

module t;

reg clk,reset;
reg [5:0] rptr;
reg  signed [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
 楼主| 发表于 2010-1-11 21:22:16 | 显示全部楼层
上面是testbench~~~
发表于 2010-1-14 20:02:34 | 显示全部楼层
always @ (posedge load)
  begin
  data_buf <= din;
  end
这个看起来就很别扭
发表于 2010-1-14 20:07:26 | 显示全部楼层
我建议用个计数器吧,每次时钟沿一来,传一位出去,并且计数器加1.  eg:
data_buf<=data_buf [NUM];
NUM <= NUM +1'b1;
if(NUM==5'd24) begin
   NUM <= 5'd0;
end
发表于 2010-1-15 12:20:32 | 显示全部楼层
学习,学习!
发表于 2010-1-15 13:04:51 | 显示全部楼层
你的load信号出来时din没有准备好,当然每次采样都是上一次的数据了。
 楼主| 发表于 2010-1-17 09:21:37 | 显示全部楼层
谢谢6楼,有个计数器是要好一些。现在想想其实要是用FSM可能更好控制一点吧
 楼主| 发表于 2010-1-17 09:33:02 | 显示全部楼层
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /1 下一条

X

小黑屋| 手机版| 关于我们| 联系我们| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2025-6-29 21:33 , Processed in 0.024713 second(s), 10 queries , Gzip On, MemCached On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表