1+ // Code your design here
2+ module AsyncFifoCustomCore # (
3+ parameter DEPTH = 16 ,
4+ parameter WIDTH = 8
5+ )(
6+ input rst,
7+
8+ input clk_w,
9+ input valid_w,
10+ output ready_w,
11+ input [WIDTH - 1 : 0 ] data_w,
12+
13+ input clk_r,
14+ output valid_r,
15+ input ready_r,
16+ output [WIDTH - 1 : 0 ] data_r
17+ );
18+ localparam PTR_WIDTH = $clog2 (DEPTH );
19+
20+
21+ wire [PTR_WIDTH : 0 ] b_wptr;
22+ wire [PTR_WIDTH : 0 ] b_rptr;
23+ wire [PTR_WIDTH : 0 ] g_wptr;
24+ wire [PTR_WIDTH : 0 ] g_rptr;
25+ wire [PTR_WIDTH : 0 ] g_wptr_sync;
26+ wire [PTR_WIDTH : 0 ] g_rptr_sync;
27+ wire full, empty;
28+
29+ Sync2Flop # (PTR_WIDTH + 1 ) wptrSync (.clk (clk_w), .rst (rst), .in (g_wptr), .out (g_wptr_sync));
30+ Sync2Flop # (PTR_WIDTH + 1 ) rptrSync (.clk (clk_r), .rst (rst), .in (g_rptr), .out (g_rptr_sync));
31+ WptrHandler # (PTR_WIDTH ) wptrHandler (.clk (clk_w), .rst (rst), .en (valid_w), .g_rptr_sync (g_rptr_sync),
32+ .g_wptr (g_wptr), .b_wptr (b_wptr), .full (full));
33+ RptrHandler # (PTR_WIDTH ) rptrHandler (.clk (clk_r), .rst (rst), .en (ready_r), .g_wptr_sync (g_wptr_sync),
34+ .g_rptr (g_rptr), .b_rptr (b_rptr), .empty (empty));
35+ Fifo # (PTR_WIDTH , WIDTH ) fifo (.rst (rst),
36+ .clk_w (clk_w), .en_w (valid_w), .data_w (data_w), .b_wptr (b_wptr), .full (full),
37+ .clk_r (clk_r), .en_r (ready_r), .data_r (data_r), .b_rptr (b_rptr), .empty (empty));
38+ assign valid_r = ~ empty;
39+ assign ready_w = ~ full;
40+
41+ endmodule
42+
43+ module Sync2Flop # (
44+ parameter PTR_WIDTH = 8
45+ )(
46+ input clk,
47+ input rst,
48+ input [PTR_WIDTH - 1 : 0 ] in,
49+ output reg [PTR_WIDTH - 1 : 0 ] out
50+ );
51+ reg [PTR_WIDTH - 1 : 0 ] mid;
52+ always_ff @ (posedge clk, negedge rst) begin
53+ if (~ rst) begin
54+ out <= '0 ;
55+ mid <= '0 ;
56+ end else begin
57+ out <= mid;
58+ mid <= in;
59+ end
60+ end
61+ endmodule
62+
63+ module WptrHandler # (
64+ parameter PTR_WIDTH = 8
65+ )(
66+ input clk,
67+ input rst,
68+ input en,
69+ input [PTR_WIDTH : 0 ] g_rptr_sync,
70+ output reg [PTR_WIDTH : 0 ] g_wptr, b_wptr,
71+ output reg full
72+ );
73+ wire [PTR_WIDTH : 0 ] g_wptr_next;
74+ wire [PTR_WIDTH : 0 ] b_wptr_next;
75+ wire full_next;
76+
77+ assign b_wptr_next = b_wptr + (en & ~ full);
78+ assign g_wptr_next = b_wptr_next ^ (b_wptr_next >> 1 );
79+ assign full_next = g_wptr_next == {~ g_rptr_sync[PTR_WIDTH : PTR_WIDTH - 1 ], g_rptr_sync[PTR_WIDTH - 2 : 0 ]} ;
80+
81+ always_ff @ (posedge clk, negedge rst) begin
82+ if (~ rst) begin
83+ g_wptr <= '0 ;
84+ b_wptr <= '0 ;
85+ full <= '0 ;
86+ // g_wptr <= g_wptr_next;
87+ // b_wptr <= b_wptr_next;
88+ // full <= full_next;
89+ end else begin
90+ g_wptr <= g_wptr_next;
91+ b_wptr <= b_wptr_next;
92+ full <= full_next;
93+ end
94+ end
95+
96+ endmodule
97+
98+ module RptrHandler # (
99+ parameter PTR_WIDTH = 8
100+ )(
101+ input clk,
102+ input rst,
103+ input en,
104+ input [PTR_WIDTH : 0 ] g_wptr_sync,
105+ output reg [PTR_WIDTH : 0 ] g_rptr, b_rptr,
106+ output reg empty
107+ );
108+ wire [PTR_WIDTH : 0 ] g_rptr_next;
109+ wire [PTR_WIDTH : 0 ] b_rptr_next;
110+ wire empty_next;
111+
112+ assign b_rptr_next = b_rptr + (en & ~ empty);
113+ assign g_rptr_next = b_rptr_next ^ (b_rptr_next >> 1 );
114+ assign empty_next = g_rptr_next == g_wptr_sync;
115+
116+ always_ff @ (posedge clk, negedge rst) begin
117+ if (~ rst) begin
118+ g_rptr <= '0 ;
119+ b_rptr <= '0 ;
120+ empty <= '1 ;
121+ end else begin
122+ g_rptr <= g_rptr_next;
123+ b_rptr <= b_rptr_next;
124+ empty <= empty_next;
125+ end
126+ end
127+
128+ endmodule
129+
130+ module Fifo # (
131+ parameter PTR_WIDTH = 8 ,
132+ parameter WIDTH = 8
133+ )(
134+ input rst,
135+ // Write
136+ input [WIDTH - 1 : 0 ] data_w,
137+ input clk_w,
138+ input en_w,
139+ input [PTR_WIDTH : 0 ] b_wptr,
140+ input full,
141+ // Read
142+ output reg [WIDTH - 1 : 0 ] data_r,
143+ input clk_r,
144+ input en_r,
145+ input [PTR_WIDTH : 0 ] b_rptr,
146+ input empty
147+ );
148+ localparam ENTRIES = 2 ** PTR_WIDTH ;
149+ integer i;
150+ reg [WIDTH - 1 : 0 ] fifoBank [0 : ENTRIES - 1 ];
151+ always_ff @ (posedge clk_w, negedge rst) begin
152+ if (~ rst) begin
153+ for (i = 0 ; i < ENTRIES ; i++ ) begin
154+ fifoBank[i] <= 'b0 ;
155+ end
156+ end else if (en_w & ~ full) begin
157+ fifoBank[b_wptr[PTR_WIDTH - 1 : 0 ]] <= data_w;
158+ end else begin
159+ for (i = 0 ; i < ENTRIES ; i++ ) begin
160+ fifoBank[i] <= fifoBank[i];
161+ end
162+ end
163+ end
164+
165+ // always_ff @(posedge clk_r) begin
166+ // if(en_r & ~empty) begin
167+ // data_r <= fifoBank[b_rptr[PTR_WIDTH-1:0]];
168+ // end
169+ // end
170+
171+ assign data_r = fifoBank[b_rptr[PTR_WIDTH - 1 : 0 ]];
172+ endmodule
173+
174+ module BinaryToGray # (
175+ parameter WIDTH = 8
176+ )(
177+ input [WIDTH - 1 : 0 ] in,
178+ output [WIDTH - 1 : 0 ] out
179+ );
180+
181+ genvar i;
182+ assign out[WIDTH - 1 ] = in[WIDTH - 1 ];
183+ for (i = WIDTH - 2 ; i >= 0 ; i-- ) begin
184+ assign out[i] = in[i] ^ in[i + 1 ];
185+ end
186+
187+ endmodule
188+
189+ module GrayToBinary # (
190+ parameter WIDTH = 8
191+ )(
192+ input [WIDTH - 1 : 0 ] in,
193+ output [WIDTH - 1 : 0 ] out
194+ );
195+ genvar i;
196+ assign out[WIDTH - 1 ] = in[WIDTH - 1 ];
197+ for (i = WIDTH - 2 ; i >= 0 ; i-- ) begin
198+ assign out[i] = ^ (in >> i);
199+ end
200+ endmodule
0 commit comments