zyyzyy的个人空间 https://blog.eetop.cn/466104 [收藏] [复制] [分享] [RSS]

空间首页 动态 记录 日志 相册 主题 分享 留言板 个人资料

日志

异步fifo设计完整代码,仿真正确-各位达人多提宝贵意见

已有 3442 次阅读| 2009-9-2 14:47

刚搞好异步fifo的设计,顶层文件为asynfifo.v

module asynfifo(wrclk,rdata,reclk,wdata,wrst_n,rrst_n,wfull,rempty);
input wrclk,reclk;
input wrst_n,rrst_n;
input [7:0] wdata;
output [7:0] rdata;
output wfull,rempty;

wire [7:0] wptr,rptr;
wire wfulle,remptye;
re_wr_logic re_wr_logic_a(.wrclk(wrclk),.wrst_n(wrst_n),.wfull(wfull),.wptr(wptr),.reclk(reclk),.rrst_n(rrst_n),.rempty(rempty),.rptr(rptr));
duralportram1 duralportram_a(.data(wdata),.wrclock(wrclk),.rdclock(reclk),.rdaddress(rptr),.rden(remptye),.wraddress(wptr),.wren(wfulle),.q(rdata));

assign wfulle=!wfull;
assign remptye=!rempty;

endmodule

子模块re_wr_logic.v(产生读写指针和空满标志)

module re_wr_logic(wrclk,wrst_n,wfull,wptr,reclk,rrst_n,rempty,rptr);
parameter n=8;
input wrclk;
//input wren;//is it needed?
input wrst_n;
output reg wfull;
output reg [n-1:0] wptr;

input reclk;
input rrst_n;
output reg rempty;
output reg [n-1:0] rptr;

reg [7:0] wbin,rbin;
wire [7:0] wbnext,wgnext,rbnext,rgnext;
wire full,empty;
wire dirset,dirrst,dirrst2;
wire high=1;//???ok!
reg direction;
reg wfull2,rempty2;
//reg [n-1:0] wptr0,wptr1,rptr0,rptr1;

always @(posedge wrclk or negedge wrst_n)//generate wptr
  if(!wrst_n)
      begin
       wptr<=8'd0;
       wbin<=8'd0;
       wfull2<=8'd0;
       wfull<=8'd0;
      end
  else begin
        wbin<=wbnext;
        wptr<=wgnext;
       end
assign wbnext=wfull?wbin:wbin+1;
assign wgnext=(wbnext>>1)^wbnext;


always @(posedge reclk or negedge rrst_n)//generate rptr
  if(!rrst_n)
      begin
       rptr<=0;
       rbin<=0;
       rempty2<=8'd0;
       rempty<=8'd0;
      end
  else begin
        rbin<=rbnext;
        rptr<=rgnext;
       end
assign rbnext=rempty?rbin:rbin+1;
assign rgnext=(rbnext>>1)^rbnext;


//generate full,wfull,empty,rempty
assign dirset=~((wptr[n-1]^rptr[n-2])&(~(wptr[n-2]^rptr[n-1])));
assign dirrst=(~(wptr[n-1]^rptr[n-2]))&(wptr[n-2]^rptr[n-1]);
assign dirrst2=~(dirrst||wrst_n);

always @(posedge high or negedge dirset or negedge dirrst2)
  if(!dirrst2) direction<=0;
  else if (!dirset)  direction<=1;
  else direction<=high;

assign full=~((wptr==rptr)&(~direction));
assign empty=~(direction&(wptr==rptr));


always @(posedge wrclk or negedge full or negedge wrst_n)
   if (!wrst_n)
      {wfull,wfull2}<=2'b00;
   else if(!full)
      {wfull,wfull2}<=2'b11;
        else
      {wfull,wfull2}<={wfull2,~full};

always @(posedge reclk or negedge empty)
   if(!empty)
      {rempty,rempty2}<=2'b11;
   else
      {rempty,rempty2}<={rempty2,~empty};

endmodule

子模块duralportram1.v(使用altera的lpm_ram_dp产生)

module duralportram1 (
 data,
 rdaddress,
 rdclock,
 rden,
 wraddress,
 wrclock,
 wren,
 q);

 input [7:0]  data;
 input [7:0]  rdaddress;
 input   rdclock;
 input   rden;
 input [7:0]  wraddress;
 input   wrclock;
 input   wren;
 output [7:0]  q;

 wire [7:0] sub_wire0;
 wire [7:0] q = sub_wire0[7:0];

 altsyncram altsyncram_component (
    .wren_a (wren),
    .clock0 (wrclock),
    .clock1 (rdclock),
    .address_a (wraddress),
    .address_b (rdaddress),
    .rden_b (rden),
    .data_a (data),
    .q_b (sub_wire0),
    .aclr0 (1'b0),
    .aclr1 (1'b0),
    .addressstall_a (1'b0),
    .addressstall_b (1'b0),
    .byteena_a (1'b1),
    .byteena_b (1'b1),
    .clocken0 (1'b1),
    .clocken1 (1'b1),
    .data_b ({8{1'b1}}),
    .q_a (),
    .wren_b (1'b0));
 defparam
  altsyncram_component.address_reg_b = "CLOCK1",
  altsyncram_component.clock_enable_input_a = "BYPASS",
  altsyncram_component.clock_enable_input_b = "BYPASS",
  altsyncram_component.clock_enable_output_b = "BYPASS",
  altsyncram_component.intended_device_family = "Cyclone II",
  altsyncram_component.lpm_type = "altsyncram",
  altsyncram_component.numwords_a = 256,
  altsyncram_component.numwords_b = 256,
  altsyncram_component.operation_mode = "DUAL_PORT",
  altsyncram_component.outdata_aclr_b = "NONE",
  altsyncram_component.outdata_reg_b = "CLOCK1",
  altsyncram_component.power_up_uninitialized = "FALSE",
  altsyncram_component.rdcontrol_reg_b = "CLOCK1",
  altsyncram_component.widthad_a = 8,
  altsyncram_component.widthad_b = 8,
  altsyncram_component.width_a = 8,
  altsyncram_component.width_b = 8,
  altsyncram_component.width_byteena_a = 1;


endmodule

本人编testbench的方法是:先考虑读频率大于写频率的情况,仿真正确,再考虑写频率大于读频率的情况,仿真正确

 


点赞

发表评论 评论 (1 个评论)

回复 伽偌 2011-5-6 09:36
楼主有QQ吗,能像你请教请教。。。

facelist

您需要登录后才可以评论 登录 | 注册

  • 关注TA
  • 加好友
  • 联系TA
  • 0

    周排名
  • 0

    月排名
  • 0

    总排名
  • 0

    关注
  • 1

    粉丝
  • 0

    好友
  • 0

    获赞
  • 15

    评论
  • 1049

    访问数
关闭

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

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

GMT+8, 2024-5-11 00:54 , Processed in 0.024279 second(s), 14 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
返回顶部