Allow the formal engine to perform a same-cycle result in the ALU
[soc.git] / unused_please_ignore_completely / iommu / axi_rab / axi_buffer_rab_bram.py
1 # this file has been generated by sv2nmigen
2
3 from nmigen import Signal, Module, Const, Cat, Elaboratable
4
5
6 class axi_buffer_rab_bram(Elaboratable):
7
8 def __init__(self):
9 self.clk = Signal() # input
10 self.rstn = Signal() # input
11 self.data_out = Signal(DATA_WIDTH) # output
12 self.valid_out = Signal() # output
13 self.ready_in = Signal() # input
14 self.valid_in = Signal() # input
15 self.data_in = Signal(DATA_WIDTH) # input
16 self.ready_out = Signal() # output
17 self.almost_full = Signal() # output
18 self.underfull = Signal() # output
19 self.drop_req = Signal() # input
20 self.drop_len = Signal(8) # input
21
22 def elaborate(self, platform=None):
23 m = Module()
24 return m
25
26
27 # // Copyright 2018 ETH Zurich and University of Bologna.
28 # // Copyright and related rights are licensed under the Solderpad Hardware
29 # // License, Version 0.51 (the "License"); you may not use this file except in
30 # // compliance with the License. You may obtain a copy of the License at
31 # // http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
32 # // or agreed to in writing, software, hardware and materials distributed under
33 # // this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
34 # // CONDITIONS OF ANY KIND, either express or implied. See the License for the
35 # // specific language governing permissions and limitations under the License.
36 #
37 # ////import CfMath::log2;
38 #
39 # module axi_buffer_rab_bram
40 # //#(
41 # // parameter DATA_WIDTH,
42 # // parameter BUFFER_DEPTH
43 # // )
44 # (
45 # input logic clk,
46 # input logic rstn,
47 #
48 # // Downstream port
49 # output logic [DATA_WIDTH-1:0] data_out,
50 # output logic valid_out,
51 # input logic ready_in,
52 #
53 # // Upstream port
54 # input logic valid_in,
55 # input logic [DATA_WIDTH-1:0] data_in,
56 # output logic ready_out,
57 #
58 # // Status and drop control
59 # output logic almost_full,
60 # output logic underfull,
61 # input logic drop_req,
62 # // Number of items to drop. As for AXI lengths, counting starts at zero, i.e., `drop_len == 0`
63 # // and `drop_req` means drop one item.
64 # input logic [7:0] drop_len
65 # );
66 #
67 """ #docstring_begin
68 // The BRAM needs to be in "write-first" mode for first-word fall-through FIFO behavior.
69 // To still push and pop simultaneously if the buffer is full, we internally increase the
70 // buffer depth by 1.
71 localparam ACT_BUFFER_DEPTH = BUFFER_DEPTH+1;
72 localparam ACT_LOG_BUFFER_DEPTH = log2(ACT_BUFFER_DEPTH+1);
73
74 /**
75 * Internal data structures
76 */
77 // Location to which we last wrote
78 logic [ACT_LOG_BUFFER_DEPTH-1:0] ptr_in_d, ptr_in_q;
79 // Location from which we last sent
80 logic [ACT_LOG_BUFFER_DEPTH-1:0] ptr_out_d, ptr_out_q;
81 // Required for fall-through behavior on the first word
82 logic [ACT_LOG_BUFFER_DEPTH-1:0] ptr_out_bram;
83 // Number of elements in the buffer. Can be negative if elements that have been dropped have not
84 // yet been written.
85 logic signed [ACT_LOG_BUFFER_DEPTH:0] n_elems_d, n_elems_q;
86
87 logic [DATA_WIDTH-1:0] data_out_bram, data_out_q;
88 logic valid_out_q;
89
90 logic full;
91
92 assign almost_full = (n_elems_q == BUFFER_DEPTH-1);
93 assign full = (n_elems_q == BUFFER_DEPTH);
94
95 always_ff @(posedge clk, negedge rstn) begin
96 if (~rstn) begin
97 n_elems_q <= '0;
98 ptr_in_q <= '0;
99 ptr_out_q <= '0;
100 end else begin
101 n_elems_q <= n_elems_d;
102 ptr_in_q <= ptr_in_d;
103 ptr_out_q <= ptr_out_d;
104 end
105 end
106
107 // Update the number of elements.
108 always_comb begin
109 n_elems_d = n_elems_q;
110 if (drop_req) begin
111 n_elems_d -= (drop_len + 1);
112 end
113 if (valid_in && ready_out) begin
114 n_elems_d += 1;
115 end
116 if (valid_out && ready_in) begin
117 n_elems_d -= 1;
118 end
119 end
120
121 // Update the output pointer.
122 always_comb begin
123 ptr_out_d = ptr_out_q;
124 if (drop_req) begin
125 if ((ptr_out_q + drop_len + 1) > (ACT_BUFFER_DEPTH - 1)) begin
126 ptr_out_d = drop_len + 1 - (ACT_BUFFER_DEPTH - ptr_out_q);
127 end else begin
128 ptr_out_d += (drop_len + 1);
129 end
130 end
131 if (valid_out && ready_in) begin
132 if (ptr_out_d == (ACT_BUFFER_DEPTH - 1)) begin
133 ptr_out_d = '0;
134 end else begin
135 ptr_out_d += 1;
136 end
137 end
138 end
139
140 // The BRAM has a read latency of one cycle, so apply the new address one cycle earlier for
141 // first-word fall-through FIFO behavior.
142 //assign ptr_out_bram = (ptr_out_q == (ACT_BUFFER_DEPTH-1)) ? '0 : (ptr_out_q + 1);
143 assign ptr_out_bram = ptr_out_d;
144
145 // Update the input pointer.
146 always_comb begin
147 ptr_in_d = ptr_in_q;
148 if (valid_in && ready_out) begin
149 if (ptr_in_d == (ACT_BUFFER_DEPTH - 1)) begin
150 ptr_in_d = '0;
151 end else begin
152 ptr_in_d += 1;
153 end
154 end
155 end
156
157 // Update output ports.
158 assign valid_out = (n_elems_q > $signed(0));
159 assign underfull = (n_elems_q < $signed(0));
160 assign ready_out = ~full;
161
162 ram_tp_write_first #(
163 .ADDR_WIDTH ( ACT_LOG_BUFFER_DEPTH ),
164 .DATA_WIDTH ( DATA_WIDTH )
165 )
166 ram_tp_write_first_0
167 (
168 .clk ( clk ),
169 .we ( valid_in & ~full ),
170 .addr0 ( ptr_in_q ),
171 .addr1 ( ptr_out_bram ),
172 .d_i ( data_in ),
173 .d0_o ( ),
174 .d1_o ( data_out_bram )
175 );
176
177 // When reading from/writing two the same address on both ports ("Write-Read Collision"),
178 // the data on the read port is invalid (during the write cycle). In this implementation,
179 // this can happen only when the buffer is empty. Thus, we forward the data from an
180 // register in this case.
181 always @(posedge clk) begin
182 if (rstn == 1'b0) begin
183 data_out_q <= 'b0;
184 end else if ( (ptr_out_bram == ptr_in_q) && (valid_in && !full) ) begin
185 data_out_q <= data_in;
186 end
187 end
188
189 always @(posedge clk) begin
190 if (rstn == 1'b0) begin
191 valid_out_q <= 'b0;
192 end else begin
193 valid_out_q <= valid_out;
194 end
195 end
196
197 // Drive output data
198 always_comb begin
199 if (valid_out && !valid_out_q) begin // We have just written to an empty FIFO
200 data_out = data_out_q;
201 end else begin
202 data_out = data_out_bram;
203 end
204 end
205
206 """
207 # endmodule
208 #
209 #