异步FIFO代码

/*
  dc_fifo_gray #( parameter dw = 64,aw=7) (
	  .rd_clk( ), 
	  .wr_clk( ), 
	  .rd_rst_n( ),
	  .wr_rst_n( ),
	  .we( ),
	  .re( ),      
	  .din( )  ,      
	  .dout ( ) ,
      .full( ) , 	
	  .empty( ) 	  
    );


*/

module dc_fifo_gray #( parameter dw = 64,aw=7) (
        input	rd_clk, wr_clk, rd_rst_n,wr_rst_n,we,re,
        input	[dw-1:0]	din ,
        output	[dw-1:0]	dout ,
        output		reg 	full , 	empty
    );
    //synopsys sync_set_reset "rd_rst_n","wr_rst_n"
 

    wire legal_we = we & (~full) ;
    wire legal_re = re & (~empty) ;

    reg	[aw:0]		wp_bin, wp_gray;
    reg	[aw:0]		rp_bin, rp_gray;
    reg	[aw:0]		wp_s, rp_s;
    reg	[aw:0]		wp_r, rp_r;// add by liwei

    wire	[aw:0]		wp_bin_next, wp_gray_next;
    wire	[aw:0]		rp_bin_next, rp_gray_next;
    wire	[aw:0]		wp_bin_x, rp_bin_x;

    simple_dc_ram  simple_dc_ram ( 
                            .rd_clk(rd_clk),
                            .wr_clk(wr_clk	),
                            .wr(legal_we),
                            .wr_addr(wp_bin[aw-1:0]),
                            .rd_addr(rp_bin[aw-1:0]	),
                            .q(dout ) ,
                            .d(din)
                        );

    always @(posedge wr_clk)
        if(!wr_rst_n)	wp_bin <= {aw+1{1'b0}};
        else
            if(legal_we)		wp_bin <= wp_bin_next;

    always @(posedge wr_clk)
        if(!wr_rst_n)	wp_gray <= {aw+1{1'b0}};
        else
            if(legal_we)		wp_gray <= wp_gray_next;

    assign wp_bin_next  = wp_bin + {{aw{1'b0}},1'b1};
    assign wp_gray_next = wp_bin_next ^ {1'b0, wp_bin_next[aw:1]};

    always @(posedge rd_clk)
        if(!rd_rst_n)	rp_bin <= {aw+1{1'b0}};
        else
            if(legal_re)		rp_bin <= rp_bin_next;

    always @(posedge rd_clk)
        if(!rd_rst_n)	rp_gray <= {aw+1{1'b0}};
        else
            if(legal_re)		rp_gray <= rp_gray_next;

    assign rp_bin_next  = rp_bin + {{aw{1'b0}},1'b1};
    assign rp_gray_next = rp_bin_next ^ {1'b0, rp_bin_next[aw:1]};

    always @(posedge rd_clk)	wp_r <= wp_gray;
    always @(posedge rd_clk)	wp_s <= wp_r;

    // read pointer
    always @(posedge wr_clk)	rp_r <= rp_gray;
    always @(posedge wr_clk)	rp_s <= rp_r;

    genvar i;

    assign wp_bin_x[aw] = wp_s[aw];
    generate
        //  assign wp_bin_x = wp_s ^ {1'b0, wp_bin_x[aw:1]};	// convert gray to binary
        for (i = (aw-1) ; i >= 0; i = i - 1) begin : WP_G2B
            assign wp_bin_x[i] = wp_s[i] ^  wp_bin_x[i+1] ;
        end

        endgenerate


    assign  rp_bin_x[aw] = rp_s[aw];
    generate
        //  assign rp_bin_x = rp_s ^ {1'b0, rp_bin_x[aw:1]};	// convert gray to binary
        for (i = (aw-1) ; i >= 0; i = i - 1) begin : RP_G2B
            assign rp_bin_x[i] = rp_s[i] ^  rp_bin_x[i+1] ;
        end

        endgenerate


            always @(posedge rd_clk)
                empty <= (wp_s == rp_gray) | (legal_re & (wp_s == rp_gray_next));

    always @(posedge wr_clk)
        full <= ((wp_bin[aw-1:0] == rp_bin_x[aw-1:0]) & (wp_bin[aw] != rp_bin_x[aw])) |
             (legal_we & (wp_bin_next[aw-1:0] == rp_bin_x[aw-1:0]) & (wp_bin_next[aw] != rp_bin_x[aw]));


endmodule





module simple_dc_ram#( parameter dw = 64,aw=7) ( //    48BIT X 8 (8 places ) if replacement nessary ?
        input rd_clk,wr_clk,wr,///wr_clk ~300Mhz   rd_clk~32Mhz
        input [aw-1:0]wr_addr,rd_addr,
        output reg [dw-1:0]q ,
        input [dw-1:0]d
    );
    //instanced (3 + 5 = 8 ) places ,
    reg	[dw-1:0]	mem [(1<<aw)-1:0];
    always @(posedge rd_clk)	q <=  mem[rd_addr];
    always @(posedge wr_clk) if (wr) mem[wr_addr] <=  d;
endmodule





 

### 回答1: Verilog异步FIFO(First-In-First-Out)代码用于实现在数据输入和输出之间进行缓冲存储的功能。以下是一个简单的Verilog异步FIFO代码的示例: module Async_FIFO( input wire clk, input wire reset, input wire data_in, input wire write_en, input wire read_en, output wire data_out ); parameter DEPTH = 8; // 定义FIFO的深度 reg [DEPTH-1:0] mem; // 存储FIFO数据的内存 reg [DEPTH-1:0] read_index; // 读取指针 reg [DEPTH-1:0] write_index; // 写入指针 always @(posedge clk or posedge reset) begin if (reset) begin mem <= 0; // 复位FIFO内存 read_index <= 0; // 复位读取指针 write_index <= 0; // 复位写入指针 end else begin if (write_en) begin mem[write_index] <= data_in; // 写入数据到FIFO内存 write_index <= write_index + 1; // 更新写入指针 end if (read_en) begin data_out <= mem[read_index]; // 从FIFO内存读取数据 read_index <= read_index + 1; // 更新读取指针 end end end endmodule 这个Verilog代码定义了一个8位深度的异步FIFO模块。它具有时钟(clk)和复位(reset)信号作为输入,并具有数据输入(data_in)、写入使能(write_en)、读取使能(read_en)和数据输出(data_out)作为其他输入和输出信号。内部使用了一个深度为8的内存数组(mem),以及读取指针(read_index)和写入指针(write_index)来实现数据的读写。 时钟上升沿触发的always块中,根据复位状态执行相应的操作。在非复位状态下,根据写入使能和读取使能的值,将数据写入FIFO内存或从FIFO内存读取数据。同时,写入指针和读取指针会相应地更新。 这是一个简单的Verilog异步FIFO代码示例,可以根据需要进行进一步的修改和扩展。 ### 回答2: Verilog是一种硬件描述语言(HDL),用于设计和描述数字电路。异步FIFO(First-In-First-Out)是一种数据存储器,可在读写操作之间解耦,通过两个独立的时钟域进行操作。下面是一个简单的异步FIFO的Verilog代码实现: ```verilog module async_fifo ( input wire clk_write, input wire rst_write, input wire write_en, input wire [7:0] data_in, output wire full, input wire clk_read, input wire rst_read, input wire read_en, output wire [7:0] data_out, output wire empty ); /* 写指针定义 */ reg [7:0] write_ptr; /* 读指针定义 */ reg [7:0] read_ptr; /* 存储器定义 */ reg [7:0] mem [255:0]; /* 写逻辑 */ always @(posedge clk_write or posedge rst_write) begin if (rst_write) write_ptr <= 8'h0; else if (write_en && ~full) write_ptr <= write_ptr + 1; end /* 读逻辑 */ always @(posedge clk_read or posedge rst_read) begin if (rst_read) read_ptr <= 8'h0; else if (read_en && ~empty) read_ptr <= read_ptr + 1; end /* 写数据 */ always @(posedge clk_write) begin if (rst_write) mem[write_ptr] <= 8'h0; else if (write_en && ~full) mem[write_ptr] <= data_in; end /* 读数据 */ always @(posedge clk_read) begin if (rst_read) data_out <= 8'h0; else if (read_en && ~empty) data_out <= mem[read_ptr]; end /* 空和满状态的判断 */ reg count; always @(posedge clk_write or posedge rst_write or posedge clk_read or posedge rst_read) begin if (rst_write || rst_read) count <= 0; else if (write_en && ~read_en && ~full) count <= count + 1; else if (~write_en && read_en && ~empty) count <= count - 1; end assign full = count == 256; assign empty = count == 0; endmodule ``` 以上是一个简单的Verilog异步FIFO代码,通过clk_write和clk_read同时控制读写操作,通过empty和full信号来判断是否为空和已满。同时,该FIFO还包含了rst_write和rst_read用于复位操作,并且可以存储256个8位数据。 ### 回答3: Verilog异步FIFO(First-In-First-Out)代码用于实现在不同速度的数据传输中的缓冲器功能。以下是一个简单的Verilog异步FIFO代码示例: module AsyncFIFO( input wire clk, input wire reset, input wire write_enable, input wire read_enable, input wire [7:0] data_in, output wire [7:0] data_out, output wire empty, output wire full ); parameter FIFO_DEPTH = 16; reg [7:0] fifo [0:FIFO_DEPTH-1]; reg [3:0] write_pointer; reg [3:0] read_pointer; reg full; reg empty; always @(posedge clk or posedge reset) begin if (reset) begin write_pointer <= 0; read_pointer <= 0; empty <= 1; full <= 0; end else begin if (write_enable) begin fifo[write_pointer] <= data_in; write_pointer <= (write_pointer + 1) % FIFO_DEPTH; empty <= 0; if (write_pointer == read_pointer) full <= 1; end if (read_enable) begin data_out <= fifo[read_pointer]; read_pointer <= (read_pointer + 1) % FIFO_DEPTH; full <= 0; if (read_pointer == write_pointer) empty <= 1; end end end endmodule 上述代码定义了一个带有时钟、复位、写使能、读使能、输入数据、输出数据以及空和满指示的FIFO模块。 模块内部使用两个指针(write_pointer和read_pointer),分别指向写入和读取数据的位置。同时使用一个数组(fifo)存储实际的数据。 在时钟上升沿或复位时,根据相应的条件进行操作。如果复位被激活,则重置指针和标志位。否则,在写使能或读使能被激活时进行相应的操作。 在写使能被激活时,将输入数据存储到fifo数组中,并更新写指针。如果写指针与读指针相等,则表示FIFO已满,将满指示位置1。 在读使能被激活时,将读指针指向的数据输出,并更新读指针。如果读指针与写指针相等,则表示FIFO为空,将空指示位置1。 以上就是一个简单的Verilog异步FIFO代码实现。实际应用中,可以根据需要对其进行扩展和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值