1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
| module asyn_fifo_top #( parameter WIDTH=8, parameter DEPTH=4 ) ( input wclk,winc,wrst_n, input rclk,rinc,rrst_n, input[WIDTH-1:0] data_i, output [WIDTH-1:0] data_o, output full, output empty ); wire [DEPTH:0] wptr,rptr; wire [DEPTH :0] r2_wptr; wire [DEPTH :0] w2_rptr; wire [DEPTH-1:0] raddr,waddr;
w2r #(DEPTH) w2r_u(.rclk(rclk),.rrst_n(rrst_n),.wptr(wptr),.r2_wptr(r2_wptr));
r2w #(DEPTH) r2w_u(.wclk(wclk),.wrst_n(wrst_n),.rptr(rptr),.w2_rptr(w2_rptr));
empty_r #(WIDTH,DEPTH) empty_u(.rclk(rclk),.rrst_n(rrst_n),.rinc(rinc),.r2_wptr(r2_wptr),.rptr(rptr),.raddr(raddr),.empty(empty));
full_w #(WIDTH,DEPTH) full_u(.wclk(wclk),.wrst_n(wrst_n),.winc(winc),.w2_rptr(w2_rptr),.wptr(wptr),.waddr(waddr),.full(full));
fifomem #(WIDTH,DEPTH) mem_u(.wclk(wclk),.winc(winc),.full(full),.raddr(raddr),.waddr(waddr),.data_i(data_i),.data_o(data_o)); endmodule
module w2r #( parameter DEPTH=4 ) ( input rclk,rrst_n, input [DEPTH:0] wptr, output reg[DEPTH:0] r2_wptr );
reg [DEPTH:0] r1_wptr;
always@(posedge rclk or negedge rrst_n) begin if(rrst_n == 1'b0) {r2_wptr,r1_wptr} <= 0; else {r2_wptr,r1_wptr} <= {r1_wptr,wptr}; end endmodule
module r2w #( parameter DEPTH=4 ) ( input wclk,wrst_n, input [DEPTH:0] rptr, output reg [DEPTH:0] w2_rptr ); reg [DEPTH:0] w1_rptr; always@(posedge wclk or negedge wrst_n) begin if(wrst_n == 1'b0) {w2_rptr,w1_rptr} <= 0; else {w2_rptr,w1_rptr} <= {w1_rptr,rptr}; end endmodule
module empty_r #( parameter WIDTH=8, parameter DEPTH=4 ) ( input rclk,rrst_n,rinc, input [DEPTH:0] r2_wptr, output reg[DEPTH:0] rptr, output [DEPTH-1:0] raddr, output reg empty ); reg [DEPTH:0] rbin; wire [DEPTH:0] binnext,graynext; wire empty_val; assign binnext = (rinc & !empty) ? rbin : rbin+1'b1; assign graynext = binnext ^ (binnext>>1); assign raddr = rbin[DEPTH-1:0]; always@(posedge rclk or negedge rrst_n) begin if(rrst_n == 1'b0) {rbin,rptr} <= 0; else {rbin,rptr} <= {binnext,graynext}; end
assign empty_val = (r2_wptr==rptr); always@(posedge rclk or negedge rrst_n) begin if(rrst_n == 1'b0) empty <= 1; else empty <= empty_val; end endmodule
module full_w #( parameter WIDTH=8, parameter DEPTH=4 ) ( input wclk,wrst_n,winc, input [DEPTH:0] w2_rptr, output reg[DEPTH:0] wptr, output [DEPTH-1:0] waddr, output reg full ); wire full_val; reg [WIDTH:0] wbin; wire [WIDTH:0] binnext,graynext;
assign waddr = wbin[WIDTH-1:0]; assign binnext = wbin + (winc & !full); assign graynext = binnext ^ (binnext>>1);
always@(posedge wclk or negedge wrst_n) begin if(wrst_n==1'b0) {wbin,wptr} <= 0; else {wbin,wptr} <= {binnext,graynext}; end
assign full_val = w2_rptr == {~wptr[DEPTH:DEPTH-1],wptr[DEPTH-2:0]}; always@(posedge wclk or negedge wrst_n) begin if(wrst_n==1'b0) full <= 1'b0; else full <= full_val; end endmodule
module fifomem #( parameter WIDTH=8, parameter DEPTH=4 ) ( input wclk,winc,full, input [DEPTH-1:0] raddr, input [DEPTH-1:0] waddr, input [WIDTH-1:0] data_i, output [WIDTH-1:0] data_o ); reg [WIDTH-1:0] memory[0:(1<<DEPTH)-1]; always@(posedge wclk ) begin if(winc & !full) memory[waddr] <= data_i; end assign data_o = memory[raddr]; endmodule
|