5
5
// ------------------------------------------------------------------------------
6
6
7
7
// INFO ------------------------------------------------------------------------
8
- // Read ahead buffer
8
+ // Read ahead buffer for FWFT fifo
9
+ //
10
+ // The buffer substitutes fifo read port and performs fifo data update at the
11
+ // same clock cycle as r_req, combinationally, for a one cycle earlier than
12
+ // it is expected from standard FWFT fifo
13
+ //
14
+ // Featires:
15
+ // - effectively increases fifo depth by one word
16
+ // - adds one cycle lateny for empty flag deassertion
17
+ // - does not touch fifo write port and full flag operation logic
18
+ // - hides all combinatorial tinkering inside
19
+ // - allows controlling and analizing fifo read signals from
20
+ // a single always_ff block, like this:
21
+ //
22
+ // always_ff @(posedge clk) begin
23
+ //
24
+ // // read control logic
25
+ // if( ~empty ) begin // masking rd_req in always_ff
26
+ // r_req <= 1'b1;
27
+ // end else begin
28
+ // r_req <= 1'b0;
29
+ // end
30
+ //
31
+ // // getting input data
32
+ // if( r_req ) begin
33
+ // new_data[] <= r_data[]; // getting data in always_ff
34
+ // end
35
+ //
36
+ // end
37
+ // end
9
38
//
10
-
11
39
12
40
/* --- INSTANTIATION TEMPLATE BEGIN ---
13
41
14
42
read_ahead_buf #(
15
43
.DATA_W( 32 )
16
- )(
44
+ ) RB1 (
17
45
.clk( ),
18
46
.anrst( ),
19
47
@@ -30,6 +58,9 @@ read_ahead_buf #(
30
58
31
59
--- INSTANTIATION TEMPLATE END ---*/
32
60
61
+ // synopsys translate_off
62
+ `define SIMULATION yes
63
+ // synopsys translate_on
33
64
34
65
module read_ahead_buf # ( parameter
35
66
DATA_W = 32
@@ -48,70 +79,67 @@ module read_ahead_buf #( parameter
48
79
output logic empty
49
80
);
50
81
51
- // buffer initialization flags
52
- logic buf_empty = 1'b1 ;
53
82
54
- // buffer fill request
55
- logic buf_fill_req;
56
- assign buf_fill_req = ~ fifo_empty &&
57
- buf_empty &&
58
- ~ buf_fill_req_d1;
83
+ logic fifo_empty_fall;
84
+ edge_detect fifo_empty_ed (
85
+ .clk ( clk ),
86
+ .anrst ( anrst ),
87
+ .in ( fifo_empty ),
88
+ .rising ( ),
89
+ .falling ( fifo_empty_fall ),
90
+ .both ( )
91
+ );
92
+
93
+ logic fantom_read;
94
+ logic normal_read;
59
95
60
- // buffer fill and re-fill cycle
61
- logic buf_fill_req_d1 = 1'b0 ;
96
+ logic buf_empty = 1'b1 ;
62
97
always_ff @ (posedge clk or negedge anrst) begin
63
98
if ( ~ anrst ) begin
64
- buf_fill_req_d1 < = 1'b0 ;
99
+ buf_empty = 1'b1 ;
65
100
end else begin
66
- buf_fill_req_d1 <= buf_fill_req;
101
+ if ( fantom_read ) begin
102
+ buf_empty <= 1'b0 ;
103
+ end else if ( fifo_empty && r_req ) begin
104
+ buf_empty = 1'b1 ;
105
+ end
67
106
end
68
107
end
69
108
70
- // filtering read requests
71
- logic r_req_filt;
72
- assign r_req_filt = anrst &&
73
- ~ fifo_empty &&
74
- ~ buf_empty &&
75
- ~ buf_fill_req && r_req;
109
+ assign fantom_read = fifo_empty_fall && buf_empty;
76
110
77
- logic r_req_rise;
78
- logic r_req_fall;
79
- edge_detect r_req_ed (
80
- .clk ( clk ),
81
- .nrst ( anrst ),
82
- .in ( r_req_filt ),
83
- .rising ( r_req_rise ),
84
- .falling ( r_req_fall ),
85
- .both ( )
86
- );
111
+ assign normal_read = r_req && ~ fifo_empty;
87
112
88
- assign fifo_r_req = r_req_filt;
89
- assign empty = anrst && fifo_empty && buf_empty;
113
+ assign empty = buf_empty || // empty falls only after fantom read
114
+ (r_req && fifo_empty); // early empty assertion
90
115
91
- // buffer itself
92
- logic [DATA_W - 1 : 0 ] r_data_buf = '0 ;
93
- always_ff @ (posedge clk or negedge anrst) begin
94
- if ( ~ anrst ) begin
95
- buf_empty = 1'b1 ;
96
- end else begin
116
+ assign fifo_r_req = anrst &&
117
+ (fantom_read || normal_read);
97
118
98
- if ( buf_fill_req_d1 ) begin
99
- r_data_buf[ DATA_W - 1 : 0 ] <= fifo_r_data[ DATA_W - 1 : 0 ] ;
100
- buf_empty = 1'b0 ;
101
- end else if ( ~ r_req_filt && r_req_fall ) begin
102
- r_data_buf[ DATA_W - 1 : 0 ] <= fifo_r_data[ DATA_W - 1 : 0 ];
103
- end
119
+ // prepare combinational signal for soft_latch
120
+ logic latch_req ;
121
+ logic [ DATA_W - 1 : 0 ] r_data_latch ;
122
+ always_comb begin
123
+ latch_req = (fantom_read || normal_read) ||
124
+ ( fifo_empty && r_req ); // buffer depletion
104
125
126
+ if ( ( fantom_read || normal_read ) ||
127
+ ( fifo_empty && r_req ) ) begin
128
+ r_data_latch[DATA_W - 1 : 0 ] = fifo_r_data[DATA_W - 1 : 0 ];
129
+ // end else if( fifo_empty && r_req ) begin // buffer depletion
130
+ // r_data_latch[DATA_W-1:0] = '0;
131
+ end else begin
132
+ r_data_latch[DATA_W - 1 : 0 ] = '0 ;
105
133
end
106
134
end
107
135
108
136
soft_latch # (
109
137
.WIDTH ( DATA_W )
110
- ) r_data_latch (
138
+ ) r_data_latch_b (
111
139
.clk ( clk ),
112
140
.anrst ( anrst ),
113
- .latch ( r_req_filt ),
114
- .in ( (r_req_rise) ? (r_data_buf [DATA_W - 1 : 0 ]) : (fifo_r_data[ DATA_W - 1 : 0 ]) ),
141
+ .latch ( latch_req ),
142
+ .in ( r_data_latch [DATA_W - 1 : 0 ] ),
115
143
.out ( r_data[DATA_W - 1 : 0 ] )
116
144
);
117
145
0 commit comments