URL
https://opencores.org/ocsvn/versatile_fifo/versatile_fifo/trunk
Subversion Repositories versatile_fifo
[/] [versatile_fifo/] [trunk/] [rtl/] [verilog/] [async_fifo_dw_simplex_actel.v] - Rev 28
Go to most recent revision | Compare with Previous | Blame | View Log
module adr_gen ( cke, q, q_bin, rst, clk); parameter length = 4; input cke; output reg [length:1] q; output [length:1] q_bin; input rst; input clk; reg [length:1] qi; wire [length:1] q_next; assign q_next = qi + {{length-1{1'b0}},1'b1}; always @ (posedge clk or posedge rst) if (rst) qi <= {length{1'b0}}; else if (cke) qi <= q_next; always @ (posedge clk or posedge rst) if (rst) q <= {length{1'b0}}; else if (cke) q <= (q_next>>1) ^ q_next; assign q_bin = qi; endmodule module vfifo_dual_port_ram_dc_dw ( d_a, q_a, adr_a, we_a, clk_a, q_b, adr_b, d_b, we_b, clk_b ); parameter DATA_WIDTH = 32; parameter ADDR_WIDTH = 8; input [(DATA_WIDTH-1):0] d_a; input [(ADDR_WIDTH-1):0] adr_a; input [(ADDR_WIDTH-1):0] adr_b; input we_a; output [(DATA_WIDTH-1):0] q_b; input [(DATA_WIDTH-1):0] d_b; output reg [(DATA_WIDTH-1):0] q_a; input we_b; input clk_a, clk_b; reg [(DATA_WIDTH-1):0] q_b; reg [DATA_WIDTH-1:0] ram [(1<<ADDR_WIDTH)-1:0] ; always @ (posedge clk_a) begin q_a <= ram[adr_a]; if (we_a) ram[adr_a] <= d_a; end always @ (posedge clk_b) begin q_b <= ram[adr_b]; if (we_b) ram[adr_b] <= d_b; end endmodule module dff_sr ( aclr, aset, clock, data, q); input aclr; input aset; input clock; input data; output reg q; always @ (posedge clock or posedge aclr or posedge aset) if (aclr) q <= 1'b0; else if (aset) q <= 1'b1; else q <= data; endmodule module versatile_fifo_async_cmp ( wptr, rptr, fifo_empty, fifo_full, wclk, rclk, rst ); parameter ADDR_WIDTH = 4; parameter N = ADDR_WIDTH-1; parameter Q1 = 2'b00; parameter Q2 = 2'b01; parameter Q3 = 2'b11; parameter Q4 = 2'b10; parameter going_empty = 1'b0; parameter going_full = 1'b1; input [N:0] wptr, rptr; output reg fifo_empty; output fifo_full; input wclk, rclk, rst; reg direction; reg direction_set, direction_clr; wire async_empty, async_full; wire fifo_full2; reg fifo_empty2; always @ (wptr[N:N-1] or rptr[N:N-1]) case ({wptr[N:N-1],rptr[N:N-1]}) {Q1,Q2} : direction_set <= 1'b1; {Q2,Q3} : direction_set <= 1'b1; {Q3,Q4} : direction_set <= 1'b1; {Q4,Q1} : direction_set <= 1'b1; default : direction_set <= 1'b0; endcase always @ (wptr[N:N-1] or rptr[N:N-1] or rst) if (rst) direction_clr <= 1'b1; else case ({wptr[N:N-1],rptr[N:N-1]}) {Q2,Q1} : direction_clr <= 1'b1; {Q3,Q2} : direction_clr <= 1'b1; {Q4,Q3} : direction_clr <= 1'b1; {Q1,Q4} : direction_clr <= 1'b1; default : direction_clr <= 1'b0; endcase always @ (posedge direction_set or posedge direction_clr) if (direction_clr) direction <= going_empty; else direction <= going_full; assign async_empty = (wptr == rptr) && (direction==going_empty); assign async_full = (wptr == rptr) && (direction==going_full); dff_sr dff_sr_empty0( .aclr(rst), .aset(async_full), .clock(wclk), .data(async_full), .q(fifo_full2)); dff_sr dff_sr_empty1( .aclr(rst), .aset(async_full), .clock(wclk), .data(fifo_full2), .q(fifo_full)); always @ (posedge rclk or posedge async_empty) if (async_empty) {fifo_empty, fifo_empty2} <= 2'b11; else {fifo_empty,fifo_empty2} <= {fifo_empty2,async_empty}; endmodule module async_fifo_dw_simplex_top ( a_d, a_wr, a_fifo_full, a_q, a_rd, a_fifo_empty, a_clk, a_rst, b_d, b_wr, b_fifo_full, b_q, b_rd, b_fifo_empty, b_clk, b_rst ); parameter data_width = 18; parameter addr_width = 4; input [data_width-1:0] a_d; input a_wr; output a_fifo_full; output [data_width-1:0] a_q; input a_rd; output a_fifo_empty; input a_clk; input a_rst; input [data_width-1:0] b_d; input b_wr; output b_fifo_full; output [data_width-1:0] b_q; input b_rd; output b_fifo_empty; input b_clk; input b_rst; wire [addr_width:1] a_wadr, a_wadr_bin, a_radr, a_radr_bin; wire [addr_width:1] b_wadr, b_wadr_bin, b_radr, b_radr_bin; wire [addr_width:0] a_dpram_adr, b_dpram_adr; adr_gen # ( .length(addr_width)) fifo_a_wr_adr( .cke(a_wr), .q(a_wadr), .q_bin(a_wadr_bin), .rst(a_rst), .clk(a_clk)); adr_gen # (.length(addr_width)) fifo_a_rd_adr( .cke(a_rd), .q(a_radr), .q_bin(a_radr_bin), .rst(a_rst), .clk(a_rst)); adr_gen # ( .length(addr_width)) fifo_b_wr_adr( .cke(b_wr), .q(b_wadr), .q_bin(b_wadr_bin), .rst(b_rst), .clk(b_clk)); adr_gen # (.length(addr_width)) fifo_b_rd_adr( .cke(b_rd), .q(b_radr), .q_bin(b_radr_bin), .rst(b_rst), .clk(b_rst)); assign a_dpram_adr = (a_wr) ? {1'b0,a_wadr_bin} : {1'b1,a_radr_bin}; assign b_dpram_adr = (b_wr) ? {1'b1,b_wadr_bin} : {1'b0,b_radr_bin}; vfifo_dual_port_ram_dc_dw # (.DATA_WIDTH(data_width), .ADDR_WIDTH(addr_width+1)) dpram ( .d_a(a_d), .q_a(a_q), .adr_a(a_dpram_adr), .we_a(a_wr), .clk_a(a_clk), .d_b(b_d), .q_b(b_q), .adr_b(b_dpram_adr), .we_b(b_wr), .clk_b(b_clk)); versatile_fifo_async_cmp # (.ADDR_WIDTH(addr_width)) cmp1 ( .wptr(a_wadr), .rptr(b_radr), .fifo_empty(b_fifo_empty), .fifo_full(a_fifo_full), .wclk(a_clk), .rclk(b_clk), .rst(a_rst) ); versatile_fifo_async_cmp # (.ADDR_WIDTH(addr_width)) cmp2 ( .wptr(b_wadr), .rptr(a_radr), .fifo_empty(a_fifo_empty), .fifo_full(b_fifo_full), .wclk(b_clk), .rclk(a_clk), .rst(b_rst) ); endmodule
Go to most recent revision | Compare with Previous | Blame | View Log