1+
2+ /*
3+ time: Mar 6, 5:31pm;
4+ ref: http://electrosofts.com/verilog/fifo.html;
5+ proj: EE287 HW, FIFO with 1k MEM
6+ */
7+
8+ // `define BUF_WIDTH 3 // MEM1k = 1k -> BUF_WIDTH = 10, no. of bits to be used in pointer
9+ `timescale 1ns/ 10ps
10+
11+ module fifo (clk,reset,push,full,din,pull,empty,dout,addrin,mdin,write,addrout,mdout);
12+
13+ parameter dout_width= 5 ;
14+ parameter stack_width= 45 ;
15+ parameter stack_height= 1024 ;
16+ parameter stack_ptr_width= 10 ;
17+ input clk, reset, push, pull;
18+ input [44 :0 ] din, mdout;
19+ output full, empty;
20+ output write;
21+ output [9 :0 ] addrin, addrout;
22+ output [44 :0 ] mdin;
23+ output [4 :0 ] dout;
24+
25+ // pointers for reading and writing
26+ reg [stack_ptr_width- 1 :0 ] read_ptr,write_ptr;
27+ // reg [stack_ptr_width:0] ptr_diff; //ptr gap size, should use height, not width
28+
29+ reg [44 :0 ] mdin_reg,mdout_reg;
30+ reg [4 :0 ] dout_reg;
31+ reg empty_reg, full_reg;
32+ // reg counter; //9-1 = 8 times to fully pullout the 45bits
33+ // reg [stack_width-1:0] stack[stack_height-1:0]; //mem1k
34+ reg [stack_width- 1 :0 ] temp; // tempary variable to store readed mdout
35+ reg [10 :0 ] fifo_counter; // ptr_diff
36+ real cnt;// 45->5 counter
37+ reg [9 :0 ] addrin_reg, addrout_reg;
38+
39+ // assign mdin = din;
40+ // assign temp = mdout; //temp is to store 45 bits and send to dout 5bits/pulse
41+ assign write = (push && ! full && ! pull && ! cnt)?1 :0 ;
42+ assign dout = dout_reg;
43+ assign full = full_reg;
44+ assign empty = empty_reg;
45+ assign addrin = addrin_reg;
46+ assign addrout = addrout_reg;
47+ assign mdin = mdin_reg;
48+
49+ always @( posedge clk or posedge reset)
50+ begin
51+ if ( reset ) begin
52+ temp <= 0 ;
53+ read_ptr <= #1 0 ;
54+ write_ptr <= #1 0 ;
55+ addrin_reg<= #1 0 ;
56+ addrout_reg<= #1 0 ;
57+ pull_cnt <= #1 0 ;
58+ // ptr_diff <= #1 0;
59+ // cnt <=#1 9;
60+ end else begin
61+ if ( pull && ! empty ) begin
62+ temp <= mdout;
63+ // cnt <= cnt -1 ;
64+ end else begin
65+ temp <= temp;
66+ // cnt <= cnt;
67+ end
68+ end
69+ end
70+
71+ // assign fifo_counter = ptr_diff;
72+ always @(fifo_counter)
73+ begin
74+ empty_reg = (fifo_counter== 0 )?1 :0 ;
75+ full_reg = (fifo_counter== stack_height)?1 :0 ;
76+ end
77+
78+ always @(posedge clk or posedge reset)
79+ begin
80+ if ( reset )
81+ fifo_counter <= 0 ;
82+ else if ( (! full && push) && ( ! empty && pull ) )
83+ fifo_counter <= fifo_counter;
84+ else if ( ! full && push )
85+ fifo_counter <= fifo_counter + 1 ;
86+ else if ( ! empty && pull ) // it is different than usual one
87+ fifo_counter <= fifo_counter - 1 ;
88+ else
89+ fifo_counter <= fifo_counter;
90+ end
91+
92+ // mimic FSM_UCB CS150
93+ always @ (posedge clk) begin
94+ if (reset) cnt <= 9 ;
95+ else
96+ if (cnt && pull) begin
97+ cnt <= #1 cnt - 1 ;
98+ end else begin
99+ cnt <= #1 cnt;
100+ end
101+ // waiting for the nine pulse
102+ // always @ (posedge clk) begin
103+ always @(* ) begin
104+ // if (cnt != 0 && pull) begin
105+ case (cnt)
106+ 0 : dout_reg <= #1 5'bxxxxx ;
107+ 1 : dout_reg <= #1 temp[4 :0 ];
108+ 2 : dout_reg <= #1 temp[9 :5 ];
109+ 3 : dout_reg <= #1 temp[14 :10 ];
110+ 4 : dout_reg <= #1 temp[19 :15 ];
111+ 5 : dout_reg <= #1 temp[24 :20 ];
112+ 6 : dout_reg <= #1 temp[29 :25 ];
113+ 7 : dout_reg <= #1 temp[34 :30 ];
114+ 8 : dout_reg <= #1 temp[39 :35 ];
115+ 9 : dout_reg <= #1 temp[44 :40 ];
116+ default : $display ("Error in cnt" );
117+ endcase
118+ end
119+ end
120+
121+ // mdout value
122+ always @(posedge clk or posedge reset)
123+ begin
124+ if ( reset ) begin
125+ mdout_reg <= 0 ;
126+ end else begin
127+ if ( pull && ! empty)
128+ mdout_reg <= mdout;
129+ end else
130+ mdout_reg <= mdout_reg;
131+ end
132+ end
133+ end
134+
135+ end else begin
136+ if ( pull && ! empty ) begin
137+ temp <= mdout;
138+ // cnt <= cnt -1 ;
139+ end else begin
140+ temp <= temp;
141+ // cnt <= cnt;
142+ end
143+
144+ // //////////////////////////////////////////////////
145+ // writing part
146+ // //////////////////////////////////////////////////
147+ // mdin value
148+ always @(posedge clk)
149+ begin
150+ if (reset)
151+ mdin_reg <= 0 ;
152+ if ( push && ! full ) begin
153+ mdin_reg <= din;
154+ end else begin
155+ mdin_reg <= mdin_reg;
156+ end
157+ end
158+
159+ // pointer
160+ always @(posedge clk or posedge reset)
161+ begin
162+ if ( reset ) begin
163+ write_ptr <= 0 ;
164+ // read_ptr <= 0;
165+ end else begin
166+ if ( ! full && push ) write_ptr <= write_ptr + 1 ;
167+ else write_ptr <= write_ptr;
168+ end
169+ /* if( !empty && pull ) read_ptr <= read_ptr + 1;
170+ else read_ptr <= read_ptr;
171+ end
172+ */
173+ end
174+
175+ // address
176+ always @(posedge clk or posedge reset)
177+ begin
178+ if ( reset )
179+ addrin_reg <= 0 ;
180+ /*if (pull && !empty && !push) begin
181+ addrout_reg = read_ptr;
182+ //temp = mdout[addrout_reg];
183+ */
184+ else
185+ if (push && ! full && ! pull) begin
186+ addrin_reg <= write_ptr;
187+ end
188+ end
189+
190+ endmodule
191+
192+ /*
193+ //pull counter
194+ //////////////////////////////////////////////////////////
195+ always @ (*) begin
196+ if (pull) pull_cnt = pull_cnt+1;
197+ else pull_cnt = pull_cnt;
198+ end
199+ //////////////////////////////////////////////////////////
200+
201+ //////////////////////////////////////////////////////////
202+ //
203+ //when (!pull && cnt = 9), I always store the next value from MEM to FIFO
204+ //to get rid of the lag!!!
205+ //////////////////////////////////////////////////////////
206+ always @ (*)
207+ begin
208+ if (pull_cnt) begin
209+ //read_ptr = 0;
210+ // mdout_reg = mdout;
211+ //end else begin
212+ if( pull ) read_ptr = read_ptr + 1;
213+ else read_ptr = read_ptr;
214+ end
215+ end
216+
217+ //////////////////////////////////////////////////////////
218+ */
0 commit comments