OpenCores
URL https://opencores.org/ocsvn/spacewire/spacewire/trunk

Subversion Repositories spacewire

[/] [spacewire/] [branches/] [ref/] [rtl/] [synfifo.v] - Blame information for rev 27

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 btltz
/*file name: synfifo.v    module:synfifo     2004-09-17pm     $btltz  from CASIC    btltz@mail.china.com
2
--    Description:    a synchronous fifo
3
--     Abbreviations:  sinit -- synchronous initial
4
                       ack -- acknowledging signal
5
                                                DWIDTH -- data width
6
                                                CWIDTH -- vector counter width
7
                                                CMAX -- maximal vector count value
8
                                                Afull -- almost full
9
                                                Hfull -- half full
10
                                                _itnl -- *_internal
11
                                                rp -- read pointer
12
                       wp -- write pointer
13
                                           alw -- allow
14
--     Modification Record:
15
                        04-09-17pm : start the draft
16
 
17
*/
18
 
19
`timescale 1ns/10ps
20
`define reset  1       //WISHBONE style reset
21
 
22
module synfifo #(parameter DEPTH =16, DWIDTH =8,
23
                              addr_max      = (DEPTH <=   16 ? 4:
24
                                               (DEPTH <=   32 ? 5:
25
                                                (DEPTH <=   64 ? 6 :
26
                                                                                         (DEPTH <=  128 ? 7 :
27
                                                                                          (DEPTH <=  256 ? 8 :
28
                                                                                                (DEPTH <=  512 ? 9 :
29
                                                                                                 (DEPTH <= 1024 ? 10 : 6 )  )))))),
30
                             CWIDTH = addr_max + 1,
31
                                                  has_wr_ack=1, has_rd_ack=1, wr_ack_low=0, rd_ack_low=0, has_count_out=1
32
                                         )
33
              (output reg [DWIDTH-1:0] dout,
34
                                   output reg full, Afull, Hfull, empty,
35
                                        output reg rd_ack, wr_ack,
36
                                        output reg rd_err, wr_err,
37
                                        output reg [CWIDTH-1:0] data_count,
38
 
39
                                        input [DWIDTH-1:0] din,
40
                                        input wr_en, rd_en,
41
                                        input gclk, sinit
42
                   );
43
 
44
 
45
 
46
integer m, i_cmax;
47
begin
48
m=0; i_cmax=1;
49
for(m=0, m<addr_max, m=m+1)    i_cmax = i_cmax * 2;
50
parameter C_MAX = i_cmax;
51
end
52
 
53
parameter avail_depth =
54
 
55
output [DWIDTH-1:0] dout;
56
output full, Afull, Hfull, empty;
57
output empty;
58
output rd_ack, wr_ack;
59
output rd_err, wr_err;
60
 
61
output [CWIDTH-1:0] data_count;   //CWIDTH-1 == addr_max.  So it can also be written as[addr_max:0] 
62
//----------------- Added outputs for internal obbscope --
63
 
64
//-----------------
65
input clk;
66
input sinit;
67
input [DWIDTH-1:0] din;
68
input wr_en;
69
input rd_en;
70
 
71
reg [DWIDTH-1:0] dout;
72
reg full, Afull, Hfull, empty;
73
reg rd_err, wr_err;
74
 
75
wire rd_ack_itn,   wr_ack_itn;
76
wire rd_ack_itnl,  wr_ack_itnl;
77
assign wd_ack     = (has_wr_ack == 0 ) ? 1'bx : wr_ack_itn;  //x will be treated as none when synthesizing
78
assign rd_ack     = (has_rd_ack == 0 ) ? 1'bx : rd_ack_itn;
79
assign wd_ack_itn = ( (wr_ack_low == 0) ? wr_ack_itnl : !wr_ack_itnl );
80
assign rd_ack_itn = ( (rd_ack_low == 0) ? rd_ack_intl : !rd_ack_itnl );
81
 
82
/*wire*/assign write_alw = (wr_en && !full);
83
/*wire*/assign read_alw = (rd_en && !empty);
84
 
85
reg [addr_max-1:0] wp,rp;
86
 
87
reg [CWIDTH-1:0] vector_cnt;    //CWIDTH = addr_max + 1
88
assign data_count = ( has_count_out == 0 ) ? { CWIDTH{1'bx} } : vector_cnt;
89
 
90
//--------------------------------------------------------------------------------------------
91
wire [DWIDTH-1:0]    mem_Dout; // Data Out from the  MemBlk
92
assign [DWIDTH-1:0] wrt_data = data_in;    //data prepare
93
 
94
//------- read /write memory Template ----------------------------------------
95
       always @(posedge clk) begin
96
              if (wr_en)
97
                      MEM[wrt_addr] <= wrt_data;
98
                  rd_addr  <= rp;
99
                          wrt_addr <= wp;
100
          end
101
//--- asy read for block RAM 
102
assign mem_Dout = MEM[rd_addr];
103
 
104
//--- registered output
105
always @(posedge gclk)
106
begin:MEM_OUTPUT
107
  if(sinit==`reset)
108
    dout <= 0;
109
  else if (rd_en==1'b1)        //change only rd_en==1 ,else hold the data; cause the SRAM's output 
110
    dout <= mem_Dout;         //is not occurs when write to the MEM.
111
end
112
 
113
 
114
//----------------------------------------------------------------------------------------------
115
 
116
/************************************************************
117
 * HandShaking Signals
118
**************************************************************/
119
//--- Read ack logic
120
always @(posedge gclk)
121
begin
122
   if(sinit==`reset)
123
     wr_ack_itnl <= 1'b0;
124
   else
125
     wr_ack_itnl <= wr_en && !full;
126
end
127
 
128
//--- write ack logic
129
always @(posedge gclk)
130
begin
131
   if(sinit==`reset)
132
      rd_ack_itnl <= 1'b0;
133
   else
134
      rd_ack_itnl <= rd_en && !empty;
135
end
136
 
137
//--- Read error handshake
138
always @(posedge gclk)
139
begin
140
   if(sinit==`reset)
141
     rd_err <= 1'b0;
142
   else
143
     rd_err <= rd_en && empty;
144
end
145
//--- Write error handshake
146
always @(posedge gclk)
147
begin
148
   if(sinit==`reset)
149
     wr_err <= 1'b0;
150
   else
151
     wr_err <= wr_en && full;
152
end
153
 
154
/***********************************************************************************
155
 * Control circuitry for FIFO.
156
 * Write only will increments  the vector_cnt, read only decrements the vector_cnt and
157
 * read && write doen't change the vector_cnt value.
158
************************************************************************************/
159
//----- Read Point
160
always @(posedge gclk)
161
begin:READ_P
162
  if (sinit==`reset)
163
     rp <= 0;
164
  else if(read_alw)  begin
165
     if (rp== (avail_depth-1) )   //need to support any arbitrary depth
166
            rp <= 0;
167
         else
168
            rp <= rp + 1'b1;
169
  end
170
end    //end block "READ_P"
171
 
172
//----- Write Point
173
always @(posedge gclk)
174
begin:WRITE_P
175
   if (sinit==`reset)
176
       wp <= 0;
177
   else if(write_alw)  begin
178
      if (wp== (avail_depth-1) )   //need to support any arbitrary depth
179
             wp <= 0;
180
          else
181
             wp <= wp + 1'b1;
182
   end
183
end   //end block "WRITE_P"1
184
 
185
//----- fifo residual vector counter
186
always @(posedge gclk)
187
begin:VECTOR_CNT
188
   if (sinit==`reset)
189
      vector_cnt <= 0;
190
   else begin
191
        case ( {write_alw, read_alw} )
192
                   2'b01:  vector_cnt <= vector_cnt - 1'b1;
193
                   2'b10:  vector_cnt <= vector_cnt + 1'b1;
194
                        default : vector_cnt <= 'bx;
195
            endcase
196
   end
197
end    //end block "VECTOR_CNT"
198
 
199
//------------------------- empty fanion ------------------------------------------------
200
//---------------- when asserted indicating the FIFO is empty -------------------------
201
always @(posedge gclk)
202
begin:EMPTY
203
   if(sinit==`reset)
204
      empty <= 1'b1;
205
   else begin
206
      if(  (vector_cnt==0 ) && ~wr_en   ||
207
               || (vector_cnt==0 ) && wr_en && rd_en
208
               (vector_cnt==1 ) && ~wr_en && rd_en   )
209
                 )
210
      empty <= 1'b1;
211
          else
212
          empty <= 1'b0;     //imply that if (vector_cnt==0 ) && wr_en && ~rd_en ), empty <= 1'b0 
213
                         //imply that if (vector_cnt==1 ) && wr_en ), empty <= 1'b0 
214
   end
215
end    //end block "EMPTY"
216
 
217
//------------------------- full fanion --------------------------------------------------
218
//---------------- when asserted indicating the fifo is full ------------------------
219
always @(posedge gclk)
220
begin:FULL
221
   if(sinit==`reset)
222
      full <= 1'b0;
223
   else begin
224
       if (  (vector_cnt==(avail_depth-1) ) && wr_en && ~rd_en   ||   //to indicate early
225
                 (vector_cnt==avail_depth) && ~rd_en  )
226
                          || vector_cnt==avail_depth) && rd_en && wr_en    //This is the conflict condition:read and write to the same cell
227
                   )
228
           full <= 1'b1;
229
           else
230
           full <= 1'b0;    //imply that if (vector_cnt==(avail_depth-1) ) && wr_en && rd_en), "full" will not be asserted
231
                        //imply that if (vector_cnt==avail_depth) && rd_en && ~wr_en), "full" will be cleared 
232
 
233
 
234
 
235
 
236
endmodule
237
`undef set
238
`undef reset

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.