propagate new use_svp64_ldst_dec mode through TestCore and TestIssuer
[soc.git] / src / unused / iommu / axi_rab / check_ram.py
1 # this file has been generated by sv2nmigen
2
3 from nmigen import Signal, Module, Const, Cat, Elaboratable
4
5
6 class check_ram(Elaboratable):
7
8 def __init__(self):
9 self.clk_i = Signal() # input
10 self.rst_ni = Signal() # input
11 self.in_addr = Signal(ADDR_WIDTH) # input
12 self.rw_type = Signal() # input
13 self.ram_we = Signal() # input
14 self.port0_addr = Signal(1+ERROR p_expression_25) # input
15 self.port1_addr = Signal(1+ERROR p_expression_25) # input
16 self.ram_wdata = Signal(RAM_DATA_WIDTH) # input
17 self.output_sent = Signal() # input
18 self.output_valid = Signal() # input
19 self.offset_addr_d = Signal(OFFSET_WIDTH) # input
20 self.hit_addr = Signal(1+ERROR p_expression_25) # output
21 self.master = Signal() # output
22 self.hit = Signal() # output
23 self.multi_hit = Signal() # output
24 self.prot = Signal() # output
25
26 def elaborate(self, platform=None):
27 m = Module()
28 return m
29
30
31 # // Copyright 2018 ETH Zurich and University of Bologna.
32 # // Copyright and related rights are licensed under the Solderpad Hardware
33 # // License, Version 0.51 (the "License"); you may not use this file except in
34 # // compliance with the License. You may obtain a copy of the License at
35 # // http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
36 # // or agreed to in writing, software, hardware and materials distributed under
37 # // this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
38 # // CONDITIONS OF ANY KIND, either express or implied. See the License for the
39 # // specific language governing permissions and limitations under the License.
40 #
41 # //import CfMath::log2;
42 #
43 # //`define MULTI_HIT_FULL_SET
44 #
45 # module check_ram
46 # //#(
47 # // parameter ADDR_WIDTH = 32,
48 # // parameter RAM_DATA_WIDTH = 32,
49 # // parameter PAGE_SIZE = 4096, // 4kB
50 # // parameter SET_WIDTH = 5,
51 # // parameter OFFSET_WIDTH = 4
52 # // )
53 # (
54 # input logic clk_i,
55 # input logic rst_ni,
56 # input logic [ADDR_WIDTH-1:0] in_addr,
57 # input logic rw_type, // 1 => write, 0=> read
58 # input logic ram_we,
59 # input logic [SET_WIDTH+OFFSET_WIDTH+1-1:0] port0_addr,
60 # input logic [SET_WIDTH+OFFSET_WIDTH+1-1:0] port1_addr,
61 # input logic [RAM_DATA_WIDTH-1:0] ram_wdata,
62 # input logic output_sent,
63 # input logic output_valid,
64 # input logic [OFFSET_WIDTH-1:0] offset_addr_d,
65 # output logic [SET_WIDTH+OFFSET_WIDTH+1-1:0] hit_addr,
66 # output logic master,
67 # output logic hit,
68 # output logic multi_hit,
69 # output logic prot
70 # );
71 #
72 """ #docstring_begin
73
74 localparam IGNORE_LSB = log2(PAGE_SIZE); // 12
75
76 logic [RAM_DATA_WIDTH-1:0] port0_data_o, port1_data_o; // RAM read data outputs
77 logic port0_hit, port1_hit; // Ram output matches in_addr
78
79 logic [SET_WIDTH+OFFSET_WIDTH+1-1:0] port0_addr_saved, port1_addr_saved;
80
81 // Hit FSM Signals
82 typedef enum logic {SEARCH, HIT} hit_state_t;
83 hit_state_t hit_SP; // Hit FSM state
84 hit_state_t hit_SN; // Hit FSM next state
85
86 // Multi Hit FSM signals
87 `ifdef MULTI_HIT_FULL_SET
88 typedef enum logic[1:0] {NO_HITS, ONE_HIT, MULTI_HIT} multi_state_t;
89 multi_state_t multi_SP; // Multi Hit FSM state
90 multi_state_t multi_SN; // Multi Hit FSM next state
91
92 logic [SET_WIDTH+OFFSET_WIDTH+1-1:0] hit_addr_saved;
93 logic master_saved;
94 `endif
95
96 //// --------------- Block RAM (Dual Port) -------------- ////
97
98 // The outputs of the BRAMs are only valid if in the previous cycle:
99 // 1. the inputs were valid, and
100 // 2. the BRAM was not written to.
101 // Otherwise, the outputs must be ignored which is controlled by the output_valid signal.
102 // This signal is driven by the uppler level L2 TLB module.
103 ram_tp_no_change #(
104 .ADDR_WIDTH( SET_WIDTH+OFFSET_WIDTH+1 ),
105 .DATA_WIDTH( RAM_DATA_WIDTH )
106 )
107 ram_tp_no_change_0
108 (
109 .clk ( clk_i ),
110 .we ( ram_we ),
111 .addr0 ( port0_addr ),
112 .addr1 ( port1_addr ),
113 .d_i ( ram_wdata ),
114 .d0_o ( port0_data_o ),
115 .d1_o ( port1_data_o )
116 );
117
118 //// Check Ram Outputs
119 assign port0_hit = (port0_data_o[0] == 1'b1) && (in_addr[ADDR_WIDTH-1: IGNORE_LSB] == port0_data_o[RAM_DATA_WIDTH-1:4]);
120 assign port1_hit = (port1_data_o[0] == 1'b1) && (in_addr[ADDR_WIDTH-1: IGNORE_LSB] == port1_data_o[RAM_DATA_WIDTH-1:4]);
121 //// ----------------------------------------------------- /////
122
123 //// ------------------- Check if Hit ------------------------ ////
124 // FSM
125 always_ff @(posedge clk_i) begin
126 if (rst_ni == 0) begin
127 hit_SP <= SEARCH;
128 end else begin
129 hit_SP <= hit_SN;
130 end
131 end
132
133 always_ff @(posedge clk_i, negedge rst_ni) begin
134 if (!rst_ni) begin
135 port0_addr_saved <= '0;
136 port1_addr_saved <= '0;
137 end else begin
138 port0_addr_saved <= port0_addr;
139 port1_addr_saved <= port1_addr;
140 end
141 end
142
143 always_comb begin
144 hit_SN = hit_SP;
145 hit = 1'b0;
146 hit_addr = 0;
147 master = 1'b0;
148 unique case(hit_SP)
149 SEARCH :
150 if (output_valid)
151 if (port0_hit || port1_hit) begin
152 hit_SN = HIT;
153 hit = 1'b1;
154 hit_addr = port0_hit ? {port0_addr_saved[SET_WIDTH+OFFSET_WIDTH:OFFSET_WIDTH], offset_addr_d} :
155 port1_hit ? {port1_addr_saved[SET_WIDTH+OFFSET_WIDTH:OFFSET_WIDTH], offset_addr_d} :
156 0;
157 master = port0_hit ? port0_data_o[3] :
158 port1_hit ? port1_data_o[3] :
159 1'b0;
160 end
161
162 HIT : begin
163 `ifdef MULTI_HIT_FULL_SET // Since the search continues after the first hit, it needs to be saved to be accessed later.
164 hit = 1'b1;
165 hit_addr = hit_addr_saved;
166 master = master_saved;
167 `endif
168 if (output_sent)
169 hit_SN = SEARCH;
170 end
171
172 default : begin
173 hit_SN = SEARCH;
174 end
175 endcase // case (hit_SP)
176 end // always_comb begin
177
178 //// ------------------------------------------- ////
179
180 assign prot = output_valid && port0_hit ? ((~port0_data_o[2] && rw_type) || (~port0_data_o[1] && ~rw_type)) :
181 output_valid && port1_hit ? ((~port1_data_o[2] && rw_type) || (~port1_data_o[1] && ~rw_type)) :
182 1'b0;
183
184 //// ------------------- Multi ------------------- ////
185 `ifdef MULTI_HIT_FULL_SET
186
187 always_ff @(posedge clk_i) begin
188 if (rst_ni == 0) begin
189 hit_addr_saved <= 0;
190 master_saved <= 1'b0;
191 end else if (output_valid) begin
192 hit_addr_saved <= hit_addr;
193 master_saved <= master;
194 end
195 end
196
197 // FSM
198 always_ff @(posedge clk_i) begin
199 if (rst_ni == 0) begin
200 multi_SP <= NO_HITS;
201 end else begin
202 multi_SP <= multi_SN;
203 end
204 end
205
206 always_comb begin
207 multi_SN = multi_SP;
208 multi_hit = 1'b0;
209 unique case(multi_SP)
210 NO_HITS :
211 if(output_valid && (port0_hit && port1_hit)) begin
212 multi_SN = MULTI_HIT;
213 multi_hit = 1'b1;
214 end else if(output_valid && (port0_hit || port1_hit))
215 multi_SN = ONE_HIT;
216
217 ONE_HIT :
218 if(output_valid && (port0_hit || port1_hit)) begin
219 multi_SN = MULTI_HIT;
220 multi_hit = 1'b1;
221 end else if (output_sent)
222 multi_SN = NO_HITS;
223
224 MULTI_HIT : begin
225 multi_hit = 1'b1;
226 if (output_sent)
227 multi_SN = NO_HITS;
228 end
229
230 endcase // case (multi_SP)
231 end // always_comb begin
232
233 `else // !`ifdef MULTI_HIT_FULL_SET
234 assign multi_hit = output_valid && port0_hit && port1_hit;
235 `endif // !`ifdef MULTI_HIT_FULL_SET
236 //// ------------------------------------------- ////
237 """
238 # endmodule
239 #
240 #