blob: 2e59215a6922bbb8eab3125b7a628e0d524694d9 [file] [log] [blame]
Sylvain Munaut21b03ba2020-09-14 10:01:45 +02001/*
2 * PicoRV32 -- A Small RISC-V (RV32I) Processor Core
3 *
4 * Copyright (C) 2015 Clifford Wolf <clifford@clifford.at>
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 */
19
20`timescale 1 ns / 1 ps
21`default_nettype none
22// `define DEBUGNETS
23// `define DEBUGREGS
24// `define DEBUGASM
25// `define DEBUG
26
27`ifdef DEBUG
28 `define debug(debug_command) debug_command
29`else
30 `define debug(debug_command)
31`endif
32
33`ifdef FORMAL
34 `define FORMAL_KEEP (* keep *)
35 `define assert(assert_expr) assert(assert_expr)
36`else
37 `ifdef DEBUGNETS
38 `define FORMAL_KEEP (* keep *)
39 `else
40 `define FORMAL_KEEP
41 `endif
42 `define assert(assert_expr) empty_statement
43`endif
44
45// uncomment this for register file in extra module
Sylvain Munautc75f71e2020-10-03 20:01:58 +020046`define PICORV32_REGS picorv32_ice40_regs
Sylvain Munaut21b03ba2020-09-14 10:01:45 +020047
48// this macro can be used to check if the verilog files in your
49// design are read in the correct order.
50`define PICORV32_V
51
52
53/***************************************************************
54 * picorv32
55 ***************************************************************/
56
57module picorv32 #(
58 parameter [ 0:0] ENABLE_COUNTERS = 1,
59 parameter [ 0:0] ENABLE_COUNTERS64 = 1,
60 parameter [ 0:0] ENABLE_REGS_16_31 = 1,
61 parameter [ 0:0] ENABLE_REGS_DUALPORT = 1,
62 parameter [ 0:0] LATCHED_MEM_RDATA = 0,
63 parameter [ 0:0] TWO_STAGE_SHIFT = 1,
64 parameter [ 0:0] BARREL_SHIFTER = 0,
65 parameter [ 0:0] TWO_CYCLE_COMPARE = 0,
66 parameter [ 0:0] TWO_CYCLE_ALU = 0,
67 parameter [ 0:0] COMPRESSED_ISA = 0,
68 parameter [ 0:0] CATCH_MISALIGN = 1,
69 parameter [ 0:0] CATCH_ILLINSN = 1,
70 parameter [ 0:0] ENABLE_PCPI = 0,
71 parameter [ 0:0] ENABLE_MUL = 0,
72 parameter [ 0:0] ENABLE_FAST_MUL = 0,
73 parameter [ 0:0] ENABLE_DIV = 0,
74 parameter [ 0:0] ENABLE_IRQ = 0,
75 parameter [ 0:0] ENABLE_IRQ_QREGS = 1,
76 parameter [ 0:0] ENABLE_IRQ_TIMER = 1,
77 parameter [ 0:0] ENABLE_TRACE = 0,
78 parameter [ 0:0] REGS_INIT_ZERO = 0,
79 parameter [31:0] MASKED_IRQ = 32'h 0000_0000,
80 parameter [31:0] LATCHED_IRQ = 32'h ffff_ffff,
81 parameter [31:0] PROGADDR_RESET = 32'h 0000_0000,
82 parameter [31:0] PROGADDR_IRQ = 32'h 0000_0010,
83 parameter [31:0] STACKADDR = 32'h ffff_ffff
84) (
85 input clk, resetn,
86 output reg trap,
87
88 output reg mem_valid,
89 output reg mem_instr,
90 input mem_ready,
91
92 output reg [31:0] mem_addr,
93 output reg [31:0] mem_wdata,
94 output reg [ 3:0] mem_wstrb,
95 input [31:0] mem_rdata,
96
97 // Look-Ahead Interface
98 output mem_la_read,
99 output mem_la_write,
100 output [31:0] mem_la_addr,
101 output reg [31:0] mem_la_wdata,
102 output reg [ 3:0] mem_la_wstrb,
103
104 // Pico Co-Processor Interface (PCPI)
105 output reg pcpi_valid,
106 output reg [31:0] pcpi_insn,
107 output [31:0] pcpi_rs1,
108 output [31:0] pcpi_rs2,
109 input pcpi_wr,
110 input [31:0] pcpi_rd,
111 input pcpi_wait,
112 input pcpi_ready,
113
114 // IRQ Interface
115 input [31:0] irq,
116 output reg [31:0] eoi,
117
118`ifdef RISCV_FORMAL
119 output reg rvfi_valid,
120 output reg [63:0] rvfi_order,
121 output reg [31:0] rvfi_insn,
122 output reg rvfi_trap,
123 output reg rvfi_halt,
124 output reg rvfi_intr,
125 output reg [ 1:0] rvfi_mode,
126 output reg [ 4:0] rvfi_rs1_addr,
127 output reg [ 4:0] rvfi_rs2_addr,
128 output reg [31:0] rvfi_rs1_rdata,
129 output reg [31:0] rvfi_rs2_rdata,
130 output reg [ 4:0] rvfi_rd_addr,
131 output reg [31:0] rvfi_rd_wdata,
132 output reg [31:0] rvfi_pc_rdata,
133 output reg [31:0] rvfi_pc_wdata,
134 output reg [31:0] rvfi_mem_addr,
135 output reg [ 3:0] rvfi_mem_rmask,
136 output reg [ 3:0] rvfi_mem_wmask,
137 output reg [31:0] rvfi_mem_rdata,
138 output reg [31:0] rvfi_mem_wdata,
139`endif
140
141 // Trace Interface
142 output reg trace_valid,
143 output reg [35:0] trace_data
144);
145 localparam integer irq_timer = 0;
146 localparam integer irq_ebreak = 1;
147 localparam integer irq_buserror = 2;
148
149 localparam integer irqregs_offset = ENABLE_REGS_16_31 ? 32 : 16;
150 localparam integer regfile_size = (ENABLE_REGS_16_31 ? 32 : 16) + 4*ENABLE_IRQ*ENABLE_IRQ_QREGS;
151 localparam integer regindex_bits = (ENABLE_REGS_16_31 ? 5 : 4) + ENABLE_IRQ*ENABLE_IRQ_QREGS;
152
153 localparam WITH_PCPI = ENABLE_PCPI || ENABLE_MUL || ENABLE_FAST_MUL || ENABLE_DIV;
154
155 localparam [35:0] TRACE_BRANCH = {4'b 0001, 32'b 0};
156 localparam [35:0] TRACE_ADDR = {4'b 0010, 32'b 0};
157 localparam [35:0] TRACE_IRQ = {4'b 1000, 32'b 0};
158
159 reg [63:0] count_cycle, count_instr;
160 reg [31:0] reg_pc, reg_next_pc, reg_op1, reg_op2, reg_out;
161 reg [4:0] reg_sh;
162
163 reg [31:0] next_insn_opcode;
164 reg [31:0] dbg_insn_opcode;
165 reg [31:0] dbg_insn_addr;
166
167 wire dbg_mem_valid = mem_valid;
168 wire dbg_mem_instr = mem_instr;
169 wire dbg_mem_ready = mem_ready;
170 wire [31:0] dbg_mem_addr = mem_addr;
171 wire [31:0] dbg_mem_wdata = mem_wdata;
172 wire [ 3:0] dbg_mem_wstrb = mem_wstrb;
173 wire [31:0] dbg_mem_rdata = mem_rdata;
174
175 assign pcpi_rs1 = reg_op1;
176 assign pcpi_rs2 = reg_op2;
177
178 wire [31:0] next_pc;
179
180 reg irq_delay;
181 reg irq_active;
182 reg [31:0] irq_mask;
183 reg [31:0] irq_pending;
184 reg [31:0] timer;
185
186`ifndef PICORV32_REGS
187 reg [31:0] cpuregs [0:regfile_size-1];
188
189 integer i;
190 initial begin
191 if (REGS_INIT_ZERO) begin
192 for (i = 0; i < regfile_size; i = i+1)
193 cpuregs[i] = 0;
194 end
195 end
196`endif
197
198 task empty_statement;
199 // This task is used by the `assert directive in non-formal mode to
200 // avoid empty statement (which are unsupported by plain Verilog syntax).
201 begin end
202 endtask
203
204`ifdef DEBUGREGS
205 wire [31:0] dbg_reg_x0 = 0;
206 wire [31:0] dbg_reg_x1 = cpuregs[1];
207 wire [31:0] dbg_reg_x2 = cpuregs[2];
208 wire [31:0] dbg_reg_x3 = cpuregs[3];
209 wire [31:0] dbg_reg_x4 = cpuregs[4];
210 wire [31:0] dbg_reg_x5 = cpuregs[5];
211 wire [31:0] dbg_reg_x6 = cpuregs[6];
212 wire [31:0] dbg_reg_x7 = cpuregs[7];
213 wire [31:0] dbg_reg_x8 = cpuregs[8];
214 wire [31:0] dbg_reg_x9 = cpuregs[9];
215 wire [31:0] dbg_reg_x10 = cpuregs[10];
216 wire [31:0] dbg_reg_x11 = cpuregs[11];
217 wire [31:0] dbg_reg_x12 = cpuregs[12];
218 wire [31:0] dbg_reg_x13 = cpuregs[13];
219 wire [31:0] dbg_reg_x14 = cpuregs[14];
220 wire [31:0] dbg_reg_x15 = cpuregs[15];
221 wire [31:0] dbg_reg_x16 = cpuregs[16];
222 wire [31:0] dbg_reg_x17 = cpuregs[17];
223 wire [31:0] dbg_reg_x18 = cpuregs[18];
224 wire [31:0] dbg_reg_x19 = cpuregs[19];
225 wire [31:0] dbg_reg_x20 = cpuregs[20];
226 wire [31:0] dbg_reg_x21 = cpuregs[21];
227 wire [31:0] dbg_reg_x22 = cpuregs[22];
228 wire [31:0] dbg_reg_x23 = cpuregs[23];
229 wire [31:0] dbg_reg_x24 = cpuregs[24];
230 wire [31:0] dbg_reg_x25 = cpuregs[25];
231 wire [31:0] dbg_reg_x26 = cpuregs[26];
232 wire [31:0] dbg_reg_x27 = cpuregs[27];
233 wire [31:0] dbg_reg_x28 = cpuregs[28];
234 wire [31:0] dbg_reg_x29 = cpuregs[29];
235 wire [31:0] dbg_reg_x30 = cpuregs[30];
236 wire [31:0] dbg_reg_x31 = cpuregs[31];
237`endif
238
239 // Internal PCPI Cores
240
241 wire pcpi_mul_wr;
242 wire [31:0] pcpi_mul_rd;
243 wire pcpi_mul_wait;
244 wire pcpi_mul_ready;
245
246 wire pcpi_div_wr;
247 wire [31:0] pcpi_div_rd;
248 wire pcpi_div_wait;
249 wire pcpi_div_ready;
250
251 reg pcpi_int_wr;
252 reg [31:0] pcpi_int_rd;
253 reg pcpi_int_wait;
254 reg pcpi_int_ready;
255
256 generate if (ENABLE_FAST_MUL) begin
257 picorv32_pcpi_fast_mul pcpi_mul (
258 .clk (clk ),
259 .resetn (resetn ),
260 .pcpi_valid(pcpi_valid ),
261 .pcpi_insn (pcpi_insn ),
262 .pcpi_rs1 (pcpi_rs1 ),
263 .pcpi_rs2 (pcpi_rs2 ),
264 .pcpi_wr (pcpi_mul_wr ),
265 .pcpi_rd (pcpi_mul_rd ),
266 .pcpi_wait (pcpi_mul_wait ),
267 .pcpi_ready(pcpi_mul_ready )
268 );
269 end else if (ENABLE_MUL) begin
270 picorv32_pcpi_mul pcpi_mul (
271 .clk (clk ),
272 .resetn (resetn ),
273 .pcpi_valid(pcpi_valid ),
274 .pcpi_insn (pcpi_insn ),
275 .pcpi_rs1 (pcpi_rs1 ),
276 .pcpi_rs2 (pcpi_rs2 ),
277 .pcpi_wr (pcpi_mul_wr ),
278 .pcpi_rd (pcpi_mul_rd ),
279 .pcpi_wait (pcpi_mul_wait ),
280 .pcpi_ready(pcpi_mul_ready )
281 );
282 end else begin
283 assign pcpi_mul_wr = 0;
284 assign pcpi_mul_rd = 32'bx;
285 assign pcpi_mul_wait = 0;
286 assign pcpi_mul_ready = 0;
287 end endgenerate
288
289 generate if (ENABLE_DIV) begin
290 picorv32_pcpi_div pcpi_div (
291 .clk (clk ),
292 .resetn (resetn ),
293 .pcpi_valid(pcpi_valid ),
294 .pcpi_insn (pcpi_insn ),
295 .pcpi_rs1 (pcpi_rs1 ),
296 .pcpi_rs2 (pcpi_rs2 ),
297 .pcpi_wr (pcpi_div_wr ),
298 .pcpi_rd (pcpi_div_rd ),
299 .pcpi_wait (pcpi_div_wait ),
300 .pcpi_ready(pcpi_div_ready )
301 );
302 end else begin
303 assign pcpi_div_wr = 0;
304 assign pcpi_div_rd = 32'bx;
305 assign pcpi_div_wait = 0;
306 assign pcpi_div_ready = 0;
307 end endgenerate
308
309 always @* begin
310 pcpi_int_wr = 0;
311 pcpi_int_rd = 32'bx;
312 pcpi_int_wait = |{ENABLE_PCPI && pcpi_wait, (ENABLE_MUL || ENABLE_FAST_MUL) && pcpi_mul_wait, ENABLE_DIV && pcpi_div_wait};
313 pcpi_int_ready = |{ENABLE_PCPI && pcpi_ready, (ENABLE_MUL || ENABLE_FAST_MUL) && pcpi_mul_ready, ENABLE_DIV && pcpi_div_ready};
314
315 (* parallel_case *)
316 case (1'b1)
317 ENABLE_PCPI && pcpi_ready: begin
318 pcpi_int_wr = ENABLE_PCPI ? pcpi_wr : 0;
319 pcpi_int_rd = ENABLE_PCPI ? pcpi_rd : 0;
320 end
321 (ENABLE_MUL || ENABLE_FAST_MUL) && pcpi_mul_ready: begin
322 pcpi_int_wr = pcpi_mul_wr;
323 pcpi_int_rd = pcpi_mul_rd;
324 end
325 ENABLE_DIV && pcpi_div_ready: begin
326 pcpi_int_wr = pcpi_div_wr;
327 pcpi_int_rd = pcpi_div_rd;
328 end
329 endcase
330 end
331
332
333 // Memory Interface
334
335 reg [1:0] mem_state;
336 reg [1:0] mem_wordsize;
337 reg [31:0] mem_rdata_word;
338 reg [31:0] mem_rdata_q;
339 reg mem_do_prefetch;
340 reg mem_do_rinst;
341 reg mem_do_rdata;
342 reg mem_do_wdata;
343
344 wire mem_xfer;
345 reg mem_la_secondword, mem_la_firstword_reg, last_mem_valid;
346 wire mem_la_firstword = COMPRESSED_ISA && (mem_do_prefetch || mem_do_rinst) && next_pc[1] && !mem_la_secondword;
347 wire mem_la_firstword_xfer = COMPRESSED_ISA && mem_xfer && (!last_mem_valid ? mem_la_firstword : mem_la_firstword_reg);
348
349 reg prefetched_high_word;
350 reg clear_prefetched_high_word;
351 reg [15:0] mem_16bit_buffer;
352
353 wire [31:0] mem_rdata_latched_noshuffle;
354 wire [31:0] mem_rdata_latched;
355
356 wire mem_la_use_prefetched_high_word = COMPRESSED_ISA && mem_la_firstword && prefetched_high_word && !clear_prefetched_high_word;
357 assign mem_xfer = (mem_valid && mem_ready) || (mem_la_use_prefetched_high_word && mem_do_rinst);
358
359 wire mem_busy = |{mem_do_prefetch, mem_do_rinst, mem_do_rdata, mem_do_wdata};
360 wire mem_done = resetn && ((mem_xfer && |mem_state && (mem_do_rinst || mem_do_rdata || mem_do_wdata)) || (&mem_state && mem_do_rinst)) &&
361 (!mem_la_firstword || (~&mem_rdata_latched[1:0] && mem_xfer));
362
363 assign mem_la_write = resetn && !mem_state && mem_do_wdata;
364 assign mem_la_read = resetn && ((!mem_la_use_prefetched_high_word && !mem_state && (mem_do_rinst || mem_do_prefetch || mem_do_rdata)) ||
365 (COMPRESSED_ISA && mem_xfer && (!last_mem_valid ? mem_la_firstword : mem_la_firstword_reg) && !mem_la_secondword && &mem_rdata_latched[1:0]));
366 assign mem_la_addr = (mem_do_prefetch || mem_do_rinst) ? {next_pc[31:2] + mem_la_firstword_xfer, 2'b00} : {reg_op1[31:2], 2'b00};
367
368 assign mem_rdata_latched_noshuffle = (mem_xfer || LATCHED_MEM_RDATA) ? mem_rdata : mem_rdata_q;
369
370 assign mem_rdata_latched = COMPRESSED_ISA && mem_la_use_prefetched_high_word ? {16'bx, mem_16bit_buffer} :
371 COMPRESSED_ISA && mem_la_secondword ? {mem_rdata_latched_noshuffle[15:0], mem_16bit_buffer} :
372 COMPRESSED_ISA && mem_la_firstword ? {16'bx, mem_rdata_latched_noshuffle[31:16]} : mem_rdata_latched_noshuffle;
373
374 always @(posedge clk) begin
375 if (!resetn) begin
376 mem_la_firstword_reg <= 0;
377 last_mem_valid <= 0;
378 end else begin
379 if (!last_mem_valid)
380 mem_la_firstword_reg <= mem_la_firstword;
381 last_mem_valid <= mem_valid && !mem_ready;
382 end
383 end
384
385 always @* begin
386 (* full_case *)
387 case (mem_wordsize)
388 0: begin
389 mem_la_wdata = reg_op2;
390 mem_la_wstrb = 4'b1111;
391 mem_rdata_word = mem_rdata;
392 end
393 1: begin
394 mem_la_wdata = {2{reg_op2[15:0]}};
395 mem_la_wstrb = reg_op1[1] ? 4'b1100 : 4'b0011;
396 case (reg_op1[1])
397 1'b0: mem_rdata_word = {16'b0, mem_rdata[15: 0]};
398 1'b1: mem_rdata_word = {16'b0, mem_rdata[31:16]};
399 endcase
400 end
401 2: begin
402 mem_la_wdata = {4{reg_op2[7:0]}};
403 mem_la_wstrb = 4'b0001 << reg_op1[1:0];
404 case (reg_op1[1:0])
405 2'b00: mem_rdata_word = {24'b0, mem_rdata[ 7: 0]};
406 2'b01: mem_rdata_word = {24'b0, mem_rdata[15: 8]};
407 2'b10: mem_rdata_word = {24'b0, mem_rdata[23:16]};
408 2'b11: mem_rdata_word = {24'b0, mem_rdata[31:24]};
409 endcase
410 end
411 endcase
412 end
413
414 always @(posedge clk) begin
415 if (mem_xfer) begin
416 mem_rdata_q <= COMPRESSED_ISA ? mem_rdata_latched : mem_rdata;
417 next_insn_opcode <= COMPRESSED_ISA ? mem_rdata_latched : mem_rdata;
418 end
419
420 if (COMPRESSED_ISA && mem_done && (mem_do_prefetch || mem_do_rinst)) begin
421 case (mem_rdata_latched[1:0])
422 2'b00: begin // Quadrant 0
423 case (mem_rdata_latched[15:13])
424 3'b000: begin // C.ADDI4SPN
425 mem_rdata_q[14:12] <= 3'b000;
426 mem_rdata_q[31:20] <= {2'b0, mem_rdata_latched[10:7], mem_rdata_latched[12:11], mem_rdata_latched[5], mem_rdata_latched[6], 2'b00};
427 end
428 3'b010: begin // C.LW
429 mem_rdata_q[31:20] <= {5'b0, mem_rdata_latched[5], mem_rdata_latched[12:10], mem_rdata_latched[6], 2'b00};
430 mem_rdata_q[14:12] <= 3'b 010;
431 end
432 3'b 110: begin // C.SW
433 {mem_rdata_q[31:25], mem_rdata_q[11:7]} <= {5'b0, mem_rdata_latched[5], mem_rdata_latched[12:10], mem_rdata_latched[6], 2'b00};
434 mem_rdata_q[14:12] <= 3'b 010;
435 end
436 endcase
437 end
438 2'b01: begin // Quadrant 1
439 case (mem_rdata_latched[15:13])
440 3'b 000: begin // C.ADDI
441 mem_rdata_q[14:12] <= 3'b000;
442 mem_rdata_q[31:20] <= $signed({mem_rdata_latched[12], mem_rdata_latched[6:2]});
443 end
444 3'b 010: begin // C.LI
445 mem_rdata_q[14:12] <= 3'b000;
446 mem_rdata_q[31:20] <= $signed({mem_rdata_latched[12], mem_rdata_latched[6:2]});
447 end
448 3'b 011: begin
449 if (mem_rdata_latched[11:7] == 2) begin // C.ADDI16SP
450 mem_rdata_q[14:12] <= 3'b000;
451 mem_rdata_q[31:20] <= $signed({mem_rdata_latched[12], mem_rdata_latched[4:3],
452 mem_rdata_latched[5], mem_rdata_latched[2], mem_rdata_latched[6], 4'b 0000});
453 end else begin // C.LUI
454 mem_rdata_q[31:12] <= $signed({mem_rdata_latched[12], mem_rdata_latched[6:2]});
455 end
456 end
457 3'b100: begin
458 if (mem_rdata_latched[11:10] == 2'b00) begin // C.SRLI
459 mem_rdata_q[31:25] <= 7'b0000000;
460 mem_rdata_q[14:12] <= 3'b 101;
461 end
462 if (mem_rdata_latched[11:10] == 2'b01) begin // C.SRAI
463 mem_rdata_q[31:25] <= 7'b0100000;
464 mem_rdata_q[14:12] <= 3'b 101;
465 end
466 if (mem_rdata_latched[11:10] == 2'b10) begin // C.ANDI
467 mem_rdata_q[14:12] <= 3'b111;
468 mem_rdata_q[31:20] <= $signed({mem_rdata_latched[12], mem_rdata_latched[6:2]});
469 end
470 if (mem_rdata_latched[12:10] == 3'b011) begin // C.SUB, C.XOR, C.OR, C.AND
471 if (mem_rdata_latched[6:5] == 2'b00) mem_rdata_q[14:12] <= 3'b000;
472 if (mem_rdata_latched[6:5] == 2'b01) mem_rdata_q[14:12] <= 3'b100;
473 if (mem_rdata_latched[6:5] == 2'b10) mem_rdata_q[14:12] <= 3'b110;
474 if (mem_rdata_latched[6:5] == 2'b11) mem_rdata_q[14:12] <= 3'b111;
475 mem_rdata_q[31:25] <= mem_rdata_latched[6:5] == 2'b00 ? 7'b0100000 : 7'b0000000;
476 end
477 end
478 3'b 110: begin // C.BEQZ
479 mem_rdata_q[14:12] <= 3'b000;
480 { mem_rdata_q[31], mem_rdata_q[7], mem_rdata_q[30:25], mem_rdata_q[11:8] } <=
481 $signed({mem_rdata_latched[12], mem_rdata_latched[6:5], mem_rdata_latched[2],
482 mem_rdata_latched[11:10], mem_rdata_latched[4:3]});
483 end
484 3'b 111: begin // C.BNEZ
485 mem_rdata_q[14:12] <= 3'b001;
486 { mem_rdata_q[31], mem_rdata_q[7], mem_rdata_q[30:25], mem_rdata_q[11:8] } <=
487 $signed({mem_rdata_latched[12], mem_rdata_latched[6:5], mem_rdata_latched[2],
488 mem_rdata_latched[11:10], mem_rdata_latched[4:3]});
489 end
490 endcase
491 end
492 2'b10: begin // Quadrant 2
493 case (mem_rdata_latched[15:13])
494 3'b000: begin // C.SLLI
495 mem_rdata_q[31:25] <= 7'b0000000;
496 mem_rdata_q[14:12] <= 3'b 001;
497 end
498 3'b010: begin // C.LWSP
499 mem_rdata_q[31:20] <= {4'b0, mem_rdata_latched[3:2], mem_rdata_latched[12], mem_rdata_latched[6:4], 2'b00};
500 mem_rdata_q[14:12] <= 3'b 010;
501 end
502 3'b100: begin
503 if (mem_rdata_latched[12] == 0 && mem_rdata_latched[6:2] == 0) begin // C.JR
504 mem_rdata_q[14:12] <= 3'b000;
505 mem_rdata_q[31:20] <= 12'b0;
506 end
507 if (mem_rdata_latched[12] == 0 && mem_rdata_latched[6:2] != 0) begin // C.MV
508 mem_rdata_q[14:12] <= 3'b000;
509 mem_rdata_q[31:25] <= 7'b0000000;
510 end
511 if (mem_rdata_latched[12] != 0 && mem_rdata_latched[11:7] != 0 && mem_rdata_latched[6:2] == 0) begin // C.JALR
512 mem_rdata_q[14:12] <= 3'b000;
513 mem_rdata_q[31:20] <= 12'b0;
514 end
515 if (mem_rdata_latched[12] != 0 && mem_rdata_latched[6:2] != 0) begin // C.ADD
516 mem_rdata_q[14:12] <= 3'b000;
517 mem_rdata_q[31:25] <= 7'b0000000;
518 end
519 end
520 3'b110: begin // C.SWSP
521 {mem_rdata_q[31:25], mem_rdata_q[11:7]} <= {4'b0, mem_rdata_latched[8:7], mem_rdata_latched[12:9], 2'b00};
522 mem_rdata_q[14:12] <= 3'b 010;
523 end
524 endcase
525 end
526 endcase
527 end
528 end
529
530 always @(posedge clk) begin
531 if (resetn && !trap) begin
532 if (mem_do_prefetch || mem_do_rinst || mem_do_rdata)
533 `assert(!mem_do_wdata);
534
535 if (mem_do_prefetch || mem_do_rinst)
536 `assert(!mem_do_rdata);
537
538 if (mem_do_rdata)
539 `assert(!mem_do_prefetch && !mem_do_rinst);
540
541 if (mem_do_wdata)
542 `assert(!(mem_do_prefetch || mem_do_rinst || mem_do_rdata));
543
544 if (mem_state == 2 || mem_state == 3)
545 `assert(mem_valid || mem_do_prefetch);
546 end
547 end
548
549 always @(posedge clk) begin
550 if (!resetn || trap) begin
551 if (!resetn)
552 mem_state <= 0;
553 if (!resetn || mem_ready)
554 mem_valid <= 0;
555 mem_la_secondword <= 0;
556 prefetched_high_word <= 0;
557 end else begin
558 if (mem_la_read || mem_la_write) begin
559 mem_addr <= mem_la_addr;
560 mem_wstrb <= mem_la_wstrb & {4{mem_la_write}};
561 end
562 if (mem_la_write) begin
563 mem_wdata <= mem_la_wdata;
564 end
565 case (mem_state)
566 0: begin
567 if (mem_do_prefetch || mem_do_rinst || mem_do_rdata) begin
568 mem_valid <= !mem_la_use_prefetched_high_word;
569 mem_instr <= mem_do_prefetch || mem_do_rinst;
570 mem_wstrb <= 0;
571 mem_state <= 1;
572 end
573 if (mem_do_wdata) begin
574 mem_valid <= 1;
575 mem_instr <= 0;
576 mem_state <= 2;
577 end
578 end
579 1: begin
580 `assert(mem_wstrb == 0);
581 `assert(mem_do_prefetch || mem_do_rinst || mem_do_rdata);
582 `assert(mem_valid == !mem_la_use_prefetched_high_word);
583 `assert(mem_instr == (mem_do_prefetch || mem_do_rinst));
584 if (mem_xfer) begin
585 if (COMPRESSED_ISA && mem_la_read) begin
586 mem_valid <= 1;
587 mem_la_secondword <= 1;
588 if (!mem_la_use_prefetched_high_word)
589 mem_16bit_buffer <= mem_rdata[31:16];
590 end else begin
591 mem_valid <= 0;
592 mem_la_secondword <= 0;
593 if (COMPRESSED_ISA && !mem_do_rdata) begin
594 if (~&mem_rdata[1:0] || mem_la_secondword) begin
595 mem_16bit_buffer <= mem_rdata[31:16];
596 prefetched_high_word <= 1;
597 end else begin
598 prefetched_high_word <= 0;
599 end
600 end
601 mem_state <= mem_do_rinst || mem_do_rdata ? 0 : 3;
602 end
603 end
604 end
605 2: begin
606 `assert(mem_wstrb != 0);
607 `assert(mem_do_wdata);
608 if (mem_xfer) begin
609 mem_valid <= 0;
610 mem_state <= 0;
611 end
612 end
613 3: begin
614 `assert(mem_wstrb == 0);
615 `assert(mem_do_prefetch);
616 if (mem_do_rinst) begin
617 mem_state <= 0;
618 end
619 end
620 endcase
621 end
622
623 if (clear_prefetched_high_word)
624 prefetched_high_word <= 0;
625 end
626
627
628 // Instruction Decoder
629
630 reg instr_lui, instr_auipc, instr_jal, instr_jalr;
631 reg instr_beq, instr_bne, instr_blt, instr_bge, instr_bltu, instr_bgeu;
632 reg instr_lb, instr_lh, instr_lw, instr_lbu, instr_lhu, instr_sb, instr_sh, instr_sw;
633 reg instr_addi, instr_slti, instr_sltiu, instr_xori, instr_ori, instr_andi, instr_slli, instr_srli, instr_srai;
634 reg instr_add, instr_sub, instr_sll, instr_slt, instr_sltu, instr_xor, instr_srl, instr_sra, instr_or, instr_and;
635 reg instr_rdcycle, instr_rdcycleh, instr_rdinstr, instr_rdinstrh, instr_ecall_ebreak;
636 reg instr_getq, instr_setq, instr_retirq, instr_maskirq, instr_waitirq, instr_timer;
637 wire instr_trap;
638
639 reg [regindex_bits-1:0] decoded_rd, decoded_rs1, decoded_rs2;
640 reg [31:0] decoded_imm, decoded_imm_uj;
641 reg decoder_trigger;
642 reg decoder_trigger_q;
643 reg decoder_pseudo_trigger;
644 reg decoder_pseudo_trigger_q;
645 reg compressed_instr;
646
647 reg is_lui_auipc_jal;
648 reg is_lb_lh_lw_lbu_lhu;
649 reg is_slli_srli_srai;
650 reg is_jalr_addi_slti_sltiu_xori_ori_andi;
651 reg is_sb_sh_sw;
652 reg is_sll_srl_sra;
653 reg is_lui_auipc_jal_jalr_addi_add_sub;
654 reg is_slti_blt_slt;
655 reg is_sltiu_bltu_sltu;
656 reg is_beq_bne_blt_bge_bltu_bgeu;
657 reg is_lbu_lhu_lw;
658 reg is_alu_reg_imm;
659 reg is_alu_reg_reg;
660 reg is_compare;
661
662 assign instr_trap = (CATCH_ILLINSN || WITH_PCPI) && !{instr_lui, instr_auipc, instr_jal, instr_jalr,
663 instr_beq, instr_bne, instr_blt, instr_bge, instr_bltu, instr_bgeu,
664 instr_lb, instr_lh, instr_lw, instr_lbu, instr_lhu, instr_sb, instr_sh, instr_sw,
665 instr_addi, instr_slti, instr_sltiu, instr_xori, instr_ori, instr_andi, instr_slli, instr_srli, instr_srai,
666 instr_add, instr_sub, instr_sll, instr_slt, instr_sltu, instr_xor, instr_srl, instr_sra, instr_or, instr_and,
667 instr_rdcycle, instr_rdcycleh, instr_rdinstr, instr_rdinstrh,
668 instr_getq, instr_setq, instr_retirq, instr_maskirq, instr_waitirq, instr_timer};
669
670 wire is_rdcycle_rdcycleh_rdinstr_rdinstrh;
671 assign is_rdcycle_rdcycleh_rdinstr_rdinstrh = |{instr_rdcycle, instr_rdcycleh, instr_rdinstr, instr_rdinstrh};
672
673 reg [63:0] new_ascii_instr;
674 `FORMAL_KEEP reg [63:0] dbg_ascii_instr;
675 `FORMAL_KEEP reg [31:0] dbg_insn_imm;
676 `FORMAL_KEEP reg [4:0] dbg_insn_rs1;
677 `FORMAL_KEEP reg [4:0] dbg_insn_rs2;
678 `FORMAL_KEEP reg [4:0] dbg_insn_rd;
679 `FORMAL_KEEP reg [31:0] dbg_rs1val;
680 `FORMAL_KEEP reg [31:0] dbg_rs2val;
681 `FORMAL_KEEP reg dbg_rs1val_valid;
682 `FORMAL_KEEP reg dbg_rs2val_valid;
683
684 always @* begin
685 new_ascii_instr = "";
686
687 if (instr_lui) new_ascii_instr = "lui";
688 if (instr_auipc) new_ascii_instr = "auipc";
689 if (instr_jal) new_ascii_instr = "jal";
690 if (instr_jalr) new_ascii_instr = "jalr";
691
692 if (instr_beq) new_ascii_instr = "beq";
693 if (instr_bne) new_ascii_instr = "bne";
694 if (instr_blt) new_ascii_instr = "blt";
695 if (instr_bge) new_ascii_instr = "bge";
696 if (instr_bltu) new_ascii_instr = "bltu";
697 if (instr_bgeu) new_ascii_instr = "bgeu";
698
699 if (instr_lb) new_ascii_instr = "lb";
700 if (instr_lh) new_ascii_instr = "lh";
701 if (instr_lw) new_ascii_instr = "lw";
702 if (instr_lbu) new_ascii_instr = "lbu";
703 if (instr_lhu) new_ascii_instr = "lhu";
704 if (instr_sb) new_ascii_instr = "sb";
705 if (instr_sh) new_ascii_instr = "sh";
706 if (instr_sw) new_ascii_instr = "sw";
707
708 if (instr_addi) new_ascii_instr = "addi";
709 if (instr_slti) new_ascii_instr = "slti";
710 if (instr_sltiu) new_ascii_instr = "sltiu";
711 if (instr_xori) new_ascii_instr = "xori";
712 if (instr_ori) new_ascii_instr = "ori";
713 if (instr_andi) new_ascii_instr = "andi";
714 if (instr_slli) new_ascii_instr = "slli";
715 if (instr_srli) new_ascii_instr = "srli";
716 if (instr_srai) new_ascii_instr = "srai";
717
718 if (instr_add) new_ascii_instr = "add";
719 if (instr_sub) new_ascii_instr = "sub";
720 if (instr_sll) new_ascii_instr = "sll";
721 if (instr_slt) new_ascii_instr = "slt";
722 if (instr_sltu) new_ascii_instr = "sltu";
723 if (instr_xor) new_ascii_instr = "xor";
724 if (instr_srl) new_ascii_instr = "srl";
725 if (instr_sra) new_ascii_instr = "sra";
726 if (instr_or) new_ascii_instr = "or";
727 if (instr_and) new_ascii_instr = "and";
728
729 if (instr_rdcycle) new_ascii_instr = "rdcycle";
730 if (instr_rdcycleh) new_ascii_instr = "rdcycleh";
731 if (instr_rdinstr) new_ascii_instr = "rdinstr";
732 if (instr_rdinstrh) new_ascii_instr = "rdinstrh";
733
734 if (instr_getq) new_ascii_instr = "getq";
735 if (instr_setq) new_ascii_instr = "setq";
736 if (instr_retirq) new_ascii_instr = "retirq";
737 if (instr_maskirq) new_ascii_instr = "maskirq";
738 if (instr_waitirq) new_ascii_instr = "waitirq";
739 if (instr_timer) new_ascii_instr = "timer";
740 end
741
742 reg [63:0] q_ascii_instr;
743 reg [31:0] q_insn_imm;
744 reg [31:0] q_insn_opcode;
745 reg [4:0] q_insn_rs1;
746 reg [4:0] q_insn_rs2;
747 reg [4:0] q_insn_rd;
748 reg dbg_next;
749
750 wire launch_next_insn;
751 reg dbg_valid_insn;
752
753 reg [63:0] cached_ascii_instr;
754 reg [31:0] cached_insn_imm;
755 reg [31:0] cached_insn_opcode;
756 reg [4:0] cached_insn_rs1;
757 reg [4:0] cached_insn_rs2;
758 reg [4:0] cached_insn_rd;
759
760 always @(posedge clk) begin
761 q_ascii_instr <= dbg_ascii_instr;
762 q_insn_imm <= dbg_insn_imm;
763 q_insn_opcode <= dbg_insn_opcode;
764 q_insn_rs1 <= dbg_insn_rs1;
765 q_insn_rs2 <= dbg_insn_rs2;
766 q_insn_rd <= dbg_insn_rd;
767 dbg_next <= launch_next_insn;
768
769 if (!resetn || trap)
770 dbg_valid_insn <= 0;
771 else if (launch_next_insn)
772 dbg_valid_insn <= 1;
773
774 if (decoder_trigger_q) begin
775 cached_ascii_instr <= new_ascii_instr;
776 cached_insn_imm <= decoded_imm;
777 if (&next_insn_opcode[1:0])
778 cached_insn_opcode <= next_insn_opcode;
779 else
780 cached_insn_opcode <= {16'b0, next_insn_opcode[15:0]};
781 cached_insn_rs1 <= decoded_rs1;
782 cached_insn_rs2 <= decoded_rs2;
783 cached_insn_rd <= decoded_rd;
784 end
785
786 if (launch_next_insn) begin
787 dbg_insn_addr <= next_pc;
788 end
789 end
790
791 always @* begin
792 dbg_ascii_instr = q_ascii_instr;
793 dbg_insn_imm = q_insn_imm;
794 dbg_insn_opcode = q_insn_opcode;
795 dbg_insn_rs1 = q_insn_rs1;
796 dbg_insn_rs2 = q_insn_rs2;
797 dbg_insn_rd = q_insn_rd;
798
799 if (dbg_next) begin
800 if (decoder_pseudo_trigger_q) begin
801 dbg_ascii_instr = cached_ascii_instr;
802 dbg_insn_imm = cached_insn_imm;
803 dbg_insn_opcode = cached_insn_opcode;
804 dbg_insn_rs1 = cached_insn_rs1;
805 dbg_insn_rs2 = cached_insn_rs2;
806 dbg_insn_rd = cached_insn_rd;
807 end else begin
808 dbg_ascii_instr = new_ascii_instr;
809 if (&next_insn_opcode[1:0])
810 dbg_insn_opcode = next_insn_opcode;
811 else
812 dbg_insn_opcode = {16'b0, next_insn_opcode[15:0]};
813 dbg_insn_imm = decoded_imm;
814 dbg_insn_rs1 = decoded_rs1;
815 dbg_insn_rs2 = decoded_rs2;
816 dbg_insn_rd = decoded_rd;
817 end
818 end
819 end
820
821`ifdef DEBUGASM
822 always @(posedge clk) begin
823 if (dbg_next) begin
824 $display("debugasm %x %x %s", dbg_insn_addr, dbg_insn_opcode, dbg_ascii_instr ? dbg_ascii_instr : "*");
825 end
826 end
827`endif
828
829`ifdef DEBUG
830 always @(posedge clk) begin
831 if (dbg_next) begin
832 if (&dbg_insn_opcode[1:0])
833 $display("DECODE: 0x%08x 0x%08x %-0s", dbg_insn_addr, dbg_insn_opcode, dbg_ascii_instr ? dbg_ascii_instr : "UNKNOWN");
834 else
835 $display("DECODE: 0x%08x 0x%04x %-0s", dbg_insn_addr, dbg_insn_opcode[15:0], dbg_ascii_instr ? dbg_ascii_instr : "UNKNOWN");
836 end
837 end
838`endif
839
840 always @(posedge clk) begin
841 is_lui_auipc_jal <= |{instr_lui, instr_auipc, instr_jal};
842 is_lui_auipc_jal_jalr_addi_add_sub <= |{instr_lui, instr_auipc, instr_jal, instr_jalr, instr_addi, instr_add, instr_sub};
843 is_slti_blt_slt <= |{instr_slti, instr_blt, instr_slt};
844 is_sltiu_bltu_sltu <= |{instr_sltiu, instr_bltu, instr_sltu};
845 is_lbu_lhu_lw <= |{instr_lbu, instr_lhu, instr_lw};
846 is_compare <= |{is_beq_bne_blt_bge_bltu_bgeu, instr_slti, instr_slt, instr_sltiu, instr_sltu};
847
848 if (mem_do_rinst && mem_done) begin
849 instr_lui <= mem_rdata_latched[6:0] == 7'b0110111;
850 instr_auipc <= mem_rdata_latched[6:0] == 7'b0010111;
851 instr_jal <= mem_rdata_latched[6:0] == 7'b1101111;
852 instr_jalr <= mem_rdata_latched[6:0] == 7'b1100111 && mem_rdata_latched[14:12] == 3'b000;
853 instr_retirq <= mem_rdata_latched[6:0] == 7'b0001011 && mem_rdata_latched[31:25] == 7'b0000010 && ENABLE_IRQ;
854 instr_waitirq <= mem_rdata_latched[6:0] == 7'b0001011 && mem_rdata_latched[31:25] == 7'b0000100 && ENABLE_IRQ;
855
856 is_beq_bne_blt_bge_bltu_bgeu <= mem_rdata_latched[6:0] == 7'b1100011;
857 is_lb_lh_lw_lbu_lhu <= mem_rdata_latched[6:0] == 7'b0000011;
858 is_sb_sh_sw <= mem_rdata_latched[6:0] == 7'b0100011;
859 is_alu_reg_imm <= mem_rdata_latched[6:0] == 7'b0010011;
860 is_alu_reg_reg <= mem_rdata_latched[6:0] == 7'b0110011;
861
862 { decoded_imm_uj[31:20], decoded_imm_uj[10:1], decoded_imm_uj[11], decoded_imm_uj[19:12], decoded_imm_uj[0] } <= $signed({mem_rdata_latched[31:12], 1'b0});
863
864 decoded_rd <= mem_rdata_latched[11:7];
865 decoded_rs1 <= mem_rdata_latched[19:15];
866 decoded_rs2 <= mem_rdata_latched[24:20];
867
868 if (mem_rdata_latched[6:0] == 7'b0001011 && mem_rdata_latched[31:25] == 7'b0000000 && ENABLE_IRQ && ENABLE_IRQ_QREGS)
869 decoded_rs1[regindex_bits-1] <= 1; // instr_getq
870
871 if (mem_rdata_latched[6:0] == 7'b0001011 && mem_rdata_latched[31:25] == 7'b0000010 && ENABLE_IRQ)
872 decoded_rs1 <= ENABLE_IRQ_QREGS ? irqregs_offset : 3; // instr_retirq
873
874 compressed_instr <= 0;
875 if (COMPRESSED_ISA && mem_rdata_latched[1:0] != 2'b11) begin
876 compressed_instr <= 1;
877 decoded_rd <= 0;
878 decoded_rs1 <= 0;
879 decoded_rs2 <= 0;
880
881 { decoded_imm_uj[31:11], decoded_imm_uj[4], decoded_imm_uj[9:8], decoded_imm_uj[10], decoded_imm_uj[6],
882 decoded_imm_uj[7], decoded_imm_uj[3:1], decoded_imm_uj[5], decoded_imm_uj[0] } <= $signed({mem_rdata_latched[12:2], 1'b0});
883
884 case (mem_rdata_latched[1:0])
885 2'b00: begin // Quadrant 0
886 case (mem_rdata_latched[15:13])
887 3'b000: begin // C.ADDI4SPN
888 is_alu_reg_imm <= |mem_rdata_latched[12:5];
889 decoded_rs1 <= 2;
890 decoded_rd <= 8 + mem_rdata_latched[4:2];
891 end
892 3'b010: begin // C.LW
893 is_lb_lh_lw_lbu_lhu <= 1;
894 decoded_rs1 <= 8 + mem_rdata_latched[9:7];
895 decoded_rd <= 8 + mem_rdata_latched[4:2];
896 end
897 3'b110: begin // C.SW
898 is_sb_sh_sw <= 1;
899 decoded_rs1 <= 8 + mem_rdata_latched[9:7];
900 decoded_rs2 <= 8 + mem_rdata_latched[4:2];
901 end
902 endcase
903 end
904 2'b01: begin // Quadrant 1
905 case (mem_rdata_latched[15:13])
906 3'b000: begin // C.NOP / C.ADDI
907 is_alu_reg_imm <= 1;
908 decoded_rd <= mem_rdata_latched[11:7];
909 decoded_rs1 <= mem_rdata_latched[11:7];
910 end
911 3'b001: begin // C.JAL
912 instr_jal <= 1;
913 decoded_rd <= 1;
914 end
915 3'b 010: begin // C.LI
916 is_alu_reg_imm <= 1;
917 decoded_rd <= mem_rdata_latched[11:7];
918 decoded_rs1 <= 0;
919 end
920 3'b 011: begin
921 if (mem_rdata_latched[12] || mem_rdata_latched[6:2]) begin
922 if (mem_rdata_latched[11:7] == 2) begin // C.ADDI16SP
923 is_alu_reg_imm <= 1;
924 decoded_rd <= mem_rdata_latched[11:7];
925 decoded_rs1 <= mem_rdata_latched[11:7];
926 end else begin // C.LUI
927 instr_lui <= 1;
928 decoded_rd <= mem_rdata_latched[11:7];
929 decoded_rs1 <= 0;
930 end
931 end
932 end
933 3'b100: begin
934 if (!mem_rdata_latched[11] && !mem_rdata_latched[12]) begin // C.SRLI, C.SRAI
935 is_alu_reg_imm <= 1;
936 decoded_rd <= 8 + mem_rdata_latched[9:7];
937 decoded_rs1 <= 8 + mem_rdata_latched[9:7];
938 decoded_rs2 <= {mem_rdata_latched[12], mem_rdata_latched[6:2]};
939 end
940 if (mem_rdata_latched[11:10] == 2'b10) begin // C.ANDI
941 is_alu_reg_imm <= 1;
942 decoded_rd <= 8 + mem_rdata_latched[9:7];
943 decoded_rs1 <= 8 + mem_rdata_latched[9:7];
944 end
945 if (mem_rdata_latched[12:10] == 3'b011) begin // C.SUB, C.XOR, C.OR, C.AND
946 is_alu_reg_reg <= 1;
947 decoded_rd <= 8 + mem_rdata_latched[9:7];
948 decoded_rs1 <= 8 + mem_rdata_latched[9:7];
949 decoded_rs2 <= 8 + mem_rdata_latched[4:2];
950 end
951 end
952 3'b101: begin // C.J
953 instr_jal <= 1;
954 end
955 3'b110: begin // C.BEQZ
956 is_beq_bne_blt_bge_bltu_bgeu <= 1;
957 decoded_rs1 <= 8 + mem_rdata_latched[9:7];
958 decoded_rs2 <= 0;
959 end
960 3'b111: begin // C.BNEZ
961 is_beq_bne_blt_bge_bltu_bgeu <= 1;
962 decoded_rs1 <= 8 + mem_rdata_latched[9:7];
963 decoded_rs2 <= 0;
964 end
965 endcase
966 end
967 2'b10: begin // Quadrant 2
968 case (mem_rdata_latched[15:13])
969 3'b000: begin // C.SLLI
970 if (!mem_rdata_latched[12]) begin
971 is_alu_reg_imm <= 1;
972 decoded_rd <= mem_rdata_latched[11:7];
973 decoded_rs1 <= mem_rdata_latched[11:7];
974 decoded_rs2 <= {mem_rdata_latched[12], mem_rdata_latched[6:2]};
975 end
976 end
977 3'b010: begin // C.LWSP
978 if (mem_rdata_latched[11:7]) begin
979 is_lb_lh_lw_lbu_lhu <= 1;
980 decoded_rd <= mem_rdata_latched[11:7];
981 decoded_rs1 <= 2;
982 end
983 end
984 3'b100: begin
985 if (mem_rdata_latched[12] == 0 && mem_rdata_latched[11:7] != 0 && mem_rdata_latched[6:2] == 0) begin // C.JR
986 instr_jalr <= 1;
987 decoded_rd <= 0;
988 decoded_rs1 <= mem_rdata_latched[11:7];
989 end
990 if (mem_rdata_latched[12] == 0 && mem_rdata_latched[6:2] != 0) begin // C.MV
991 is_alu_reg_reg <= 1;
992 decoded_rd <= mem_rdata_latched[11:7];
993 decoded_rs1 <= 0;
994 decoded_rs2 <= mem_rdata_latched[6:2];
995 end
996 if (mem_rdata_latched[12] != 0 && mem_rdata_latched[11:7] != 0 && mem_rdata_latched[6:2] == 0) begin // C.JALR
997 instr_jalr <= 1;
998 decoded_rd <= 1;
999 decoded_rs1 <= mem_rdata_latched[11:7];
1000 end
1001 if (mem_rdata_latched[12] != 0 && mem_rdata_latched[6:2] != 0) begin // C.ADD
1002 is_alu_reg_reg <= 1;
1003 decoded_rd <= mem_rdata_latched[11:7];
1004 decoded_rs1 <= mem_rdata_latched[11:7];
1005 decoded_rs2 <= mem_rdata_latched[6:2];
1006 end
1007 end
1008 3'b110: begin // C.SWSP
1009 is_sb_sh_sw <= 1;
1010 decoded_rs1 <= 2;
1011 decoded_rs2 <= mem_rdata_latched[6:2];
1012 end
1013 endcase
1014 end
1015 endcase
1016 end
1017 end
1018
1019 if (decoder_trigger && !decoder_pseudo_trigger) begin
1020 pcpi_insn <= WITH_PCPI ? mem_rdata_q : 'bx;
1021
1022 instr_beq <= is_beq_bne_blt_bge_bltu_bgeu && mem_rdata_q[14:12] == 3'b000;
1023 instr_bne <= is_beq_bne_blt_bge_bltu_bgeu && mem_rdata_q[14:12] == 3'b001;
1024 instr_blt <= is_beq_bne_blt_bge_bltu_bgeu && mem_rdata_q[14:12] == 3'b100;
1025 instr_bge <= is_beq_bne_blt_bge_bltu_bgeu && mem_rdata_q[14:12] == 3'b101;
1026 instr_bltu <= is_beq_bne_blt_bge_bltu_bgeu && mem_rdata_q[14:12] == 3'b110;
1027 instr_bgeu <= is_beq_bne_blt_bge_bltu_bgeu && mem_rdata_q[14:12] == 3'b111;
1028
1029 instr_lb <= is_lb_lh_lw_lbu_lhu && mem_rdata_q[14:12] == 3'b000;
1030 instr_lh <= is_lb_lh_lw_lbu_lhu && mem_rdata_q[14:12] == 3'b001;
1031 instr_lw <= is_lb_lh_lw_lbu_lhu && mem_rdata_q[14:12] == 3'b010;
1032 instr_lbu <= is_lb_lh_lw_lbu_lhu && mem_rdata_q[14:12] == 3'b100;
1033 instr_lhu <= is_lb_lh_lw_lbu_lhu && mem_rdata_q[14:12] == 3'b101;
1034
1035 instr_sb <= is_sb_sh_sw && mem_rdata_q[14:12] == 3'b000;
1036 instr_sh <= is_sb_sh_sw && mem_rdata_q[14:12] == 3'b001;
1037 instr_sw <= is_sb_sh_sw && mem_rdata_q[14:12] == 3'b010;
1038
1039 instr_addi <= is_alu_reg_imm && mem_rdata_q[14:12] == 3'b000;
1040 instr_slti <= is_alu_reg_imm && mem_rdata_q[14:12] == 3'b010;
1041 instr_sltiu <= is_alu_reg_imm && mem_rdata_q[14:12] == 3'b011;
1042 instr_xori <= is_alu_reg_imm && mem_rdata_q[14:12] == 3'b100;
1043 instr_ori <= is_alu_reg_imm && mem_rdata_q[14:12] == 3'b110;
1044 instr_andi <= is_alu_reg_imm && mem_rdata_q[14:12] == 3'b111;
1045
1046 instr_slli <= is_alu_reg_imm && mem_rdata_q[14:12] == 3'b001 && mem_rdata_q[31:25] == 7'b0000000;
1047 instr_srli <= is_alu_reg_imm && mem_rdata_q[14:12] == 3'b101 && mem_rdata_q[31:25] == 7'b0000000;
1048 instr_srai <= is_alu_reg_imm && mem_rdata_q[14:12] == 3'b101 && mem_rdata_q[31:25] == 7'b0100000;
1049
1050 instr_add <= is_alu_reg_reg && mem_rdata_q[14:12] == 3'b000 && mem_rdata_q[31:25] == 7'b0000000;
1051 instr_sub <= is_alu_reg_reg && mem_rdata_q[14:12] == 3'b000 && mem_rdata_q[31:25] == 7'b0100000;
1052 instr_sll <= is_alu_reg_reg && mem_rdata_q[14:12] == 3'b001 && mem_rdata_q[31:25] == 7'b0000000;
1053 instr_slt <= is_alu_reg_reg && mem_rdata_q[14:12] == 3'b010 && mem_rdata_q[31:25] == 7'b0000000;
1054 instr_sltu <= is_alu_reg_reg && mem_rdata_q[14:12] == 3'b011 && mem_rdata_q[31:25] == 7'b0000000;
1055 instr_xor <= is_alu_reg_reg && mem_rdata_q[14:12] == 3'b100 && mem_rdata_q[31:25] == 7'b0000000;
1056 instr_srl <= is_alu_reg_reg && mem_rdata_q[14:12] == 3'b101 && mem_rdata_q[31:25] == 7'b0000000;
1057 instr_sra <= is_alu_reg_reg && mem_rdata_q[14:12] == 3'b101 && mem_rdata_q[31:25] == 7'b0100000;
1058 instr_or <= is_alu_reg_reg && mem_rdata_q[14:12] == 3'b110 && mem_rdata_q[31:25] == 7'b0000000;
1059 instr_and <= is_alu_reg_reg && mem_rdata_q[14:12] == 3'b111 && mem_rdata_q[31:25] == 7'b0000000;
1060
1061 instr_rdcycle <= ((mem_rdata_q[6:0] == 7'b1110011 && mem_rdata_q[31:12] == 'b11000000000000000010) ||
1062 (mem_rdata_q[6:0] == 7'b1110011 && mem_rdata_q[31:12] == 'b11000000000100000010)) && ENABLE_COUNTERS;
1063 instr_rdcycleh <= ((mem_rdata_q[6:0] == 7'b1110011 && mem_rdata_q[31:12] == 'b11001000000000000010) ||
1064 (mem_rdata_q[6:0] == 7'b1110011 && mem_rdata_q[31:12] == 'b11001000000100000010)) && ENABLE_COUNTERS && ENABLE_COUNTERS64;
1065 instr_rdinstr <= (mem_rdata_q[6:0] == 7'b1110011 && mem_rdata_q[31:12] == 'b11000000001000000010) && ENABLE_COUNTERS;
1066 instr_rdinstrh <= (mem_rdata_q[6:0] == 7'b1110011 && mem_rdata_q[31:12] == 'b11001000001000000010) && ENABLE_COUNTERS && ENABLE_COUNTERS64;
1067
1068 instr_ecall_ebreak <= ((mem_rdata_q[6:0] == 7'b1110011 && !mem_rdata_q[31:21] && !mem_rdata_q[19:7]) ||
1069 (COMPRESSED_ISA && mem_rdata_q[15:0] == 16'h9002));
1070
1071 instr_getq <= mem_rdata_q[6:0] == 7'b0001011 && mem_rdata_q[31:25] == 7'b0000000 && ENABLE_IRQ && ENABLE_IRQ_QREGS;
1072 instr_setq <= mem_rdata_q[6:0] == 7'b0001011 && mem_rdata_q[31:25] == 7'b0000001 && ENABLE_IRQ && ENABLE_IRQ_QREGS;
1073 instr_maskirq <= mem_rdata_q[6:0] == 7'b0001011 && mem_rdata_q[31:25] == 7'b0000011 && ENABLE_IRQ;
1074 instr_timer <= mem_rdata_q[6:0] == 7'b0001011 && mem_rdata_q[31:25] == 7'b0000101 && ENABLE_IRQ && ENABLE_IRQ_TIMER;
1075
1076 is_slli_srli_srai <= is_alu_reg_imm && |{
1077 mem_rdata_q[14:12] == 3'b001 && mem_rdata_q[31:25] == 7'b0000000,
1078 mem_rdata_q[14:12] == 3'b101 && mem_rdata_q[31:25] == 7'b0000000,
1079 mem_rdata_q[14:12] == 3'b101 && mem_rdata_q[31:25] == 7'b0100000
1080 };
1081
1082 is_jalr_addi_slti_sltiu_xori_ori_andi <= instr_jalr || is_alu_reg_imm && |{
1083 mem_rdata_q[14:12] == 3'b000,
1084 mem_rdata_q[14:12] == 3'b010,
1085 mem_rdata_q[14:12] == 3'b011,
1086 mem_rdata_q[14:12] == 3'b100,
1087 mem_rdata_q[14:12] == 3'b110,
1088 mem_rdata_q[14:12] == 3'b111
1089 };
1090
1091 is_sll_srl_sra <= is_alu_reg_reg && |{
1092 mem_rdata_q[14:12] == 3'b001 && mem_rdata_q[31:25] == 7'b0000000,
1093 mem_rdata_q[14:12] == 3'b101 && mem_rdata_q[31:25] == 7'b0000000,
1094 mem_rdata_q[14:12] == 3'b101 && mem_rdata_q[31:25] == 7'b0100000
1095 };
1096
1097 is_lui_auipc_jal_jalr_addi_add_sub <= 0;
1098 is_compare <= 0;
1099
1100 (* parallel_case *)
1101 case (1'b1)
1102 instr_jal:
1103 decoded_imm <= decoded_imm_uj;
1104 |{instr_lui, instr_auipc}:
1105 decoded_imm <= mem_rdata_q[31:12] << 12;
1106 |{instr_jalr, is_lb_lh_lw_lbu_lhu, is_alu_reg_imm}:
1107 decoded_imm <= $signed(mem_rdata_q[31:20]);
1108 is_beq_bne_blt_bge_bltu_bgeu:
1109 decoded_imm <= $signed({mem_rdata_q[31], mem_rdata_q[7], mem_rdata_q[30:25], mem_rdata_q[11:8], 1'b0});
1110 is_sb_sh_sw:
1111 decoded_imm <= $signed({mem_rdata_q[31:25], mem_rdata_q[11:7]});
1112 default:
1113 decoded_imm <= 1'bx;
1114 endcase
1115 end
1116
1117 if (!resetn) begin
1118 is_beq_bne_blt_bge_bltu_bgeu <= 0;
1119 is_compare <= 0;
1120
1121 instr_beq <= 0;
1122 instr_bne <= 0;
1123 instr_blt <= 0;
1124 instr_bge <= 0;
1125 instr_bltu <= 0;
1126 instr_bgeu <= 0;
1127
1128 instr_addi <= 0;
1129 instr_slti <= 0;
1130 instr_sltiu <= 0;
1131 instr_xori <= 0;
1132 instr_ori <= 0;
1133 instr_andi <= 0;
1134
1135 instr_add <= 0;
1136 instr_sub <= 0;
1137 instr_sll <= 0;
1138 instr_slt <= 0;
1139 instr_sltu <= 0;
1140 instr_xor <= 0;
1141 instr_srl <= 0;
1142 instr_sra <= 0;
1143 instr_or <= 0;
1144 instr_and <= 0;
1145 end
1146 end
1147
1148
1149 // Main State Machine
1150
1151 localparam cpu_state_trap = 8'b10000000;
1152 localparam cpu_state_fetch = 8'b01000000;
1153 localparam cpu_state_ld_rs1 = 8'b00100000;
1154 localparam cpu_state_ld_rs2 = 8'b00010000;
1155 localparam cpu_state_exec = 8'b00001000;
1156 localparam cpu_state_shift = 8'b00000100;
1157 localparam cpu_state_stmem = 8'b00000010;
1158 localparam cpu_state_ldmem = 8'b00000001;
1159
1160 reg [7:0] cpu_state;
1161 reg [1:0] irq_state;
1162
1163 `FORMAL_KEEP reg [127:0] dbg_ascii_state;
1164
1165 always @* begin
1166 dbg_ascii_state = "";
1167 if (cpu_state == cpu_state_trap) dbg_ascii_state = "trap";
1168 if (cpu_state == cpu_state_fetch) dbg_ascii_state = "fetch";
1169 if (cpu_state == cpu_state_ld_rs1) dbg_ascii_state = "ld_rs1";
1170 if (cpu_state == cpu_state_ld_rs2) dbg_ascii_state = "ld_rs2";
1171 if (cpu_state == cpu_state_exec) dbg_ascii_state = "exec";
1172 if (cpu_state == cpu_state_shift) dbg_ascii_state = "shift";
1173 if (cpu_state == cpu_state_stmem) dbg_ascii_state = "stmem";
1174 if (cpu_state == cpu_state_ldmem) dbg_ascii_state = "ldmem";
1175 end
1176
1177 reg set_mem_do_rinst;
1178 reg set_mem_do_rdata;
1179 reg set_mem_do_wdata;
1180
1181 reg latched_store;
1182 reg latched_stalu;
1183 reg latched_branch;
1184 reg latched_compr;
1185 reg latched_trace;
1186 reg latched_is_lu;
1187 reg latched_is_lh;
1188 reg latched_is_lb;
1189 reg [regindex_bits-1:0] latched_rd;
1190
1191 reg [31:0] current_pc;
1192 assign next_pc = latched_store && latched_branch ? reg_out & ~1 : reg_next_pc;
1193
1194 reg [3:0] pcpi_timeout_counter;
1195 reg pcpi_timeout;
1196
1197 reg [31:0] next_irq_pending;
1198 reg do_waitirq;
1199
1200 reg [31:0] alu_out, alu_out_q;
1201 reg alu_out_0, alu_out_0_q;
1202 reg alu_wait, alu_wait_2;
1203
1204 reg [31:0] alu_add_sub;
1205 reg [31:0] alu_shl, alu_shr;
1206 reg alu_eq, alu_ltu, alu_lts;
1207
1208 generate if (TWO_CYCLE_ALU) begin
1209 always @(posedge clk) begin
1210 alu_add_sub <= instr_sub ? reg_op1 - reg_op2 : reg_op1 + reg_op2;
1211 alu_eq <= reg_op1 == reg_op2;
1212 alu_lts <= $signed(reg_op1) < $signed(reg_op2);
1213 alu_ltu <= reg_op1 < reg_op2;
1214 alu_shl <= reg_op1 << reg_op2[4:0];
1215 alu_shr <= $signed({instr_sra || instr_srai ? reg_op1[31] : 1'b0, reg_op1}) >>> reg_op2[4:0];
1216 end
1217 end else begin
1218 always @* begin
1219 alu_add_sub = instr_sub ? reg_op1 - reg_op2 : reg_op1 + reg_op2;
1220 alu_eq = reg_op1 == reg_op2;
1221 alu_lts = $signed(reg_op1) < $signed(reg_op2);
1222 alu_ltu = reg_op1 < reg_op2;
1223 alu_shl = reg_op1 << reg_op2[4:0];
1224 alu_shr = $signed({instr_sra || instr_srai ? reg_op1[31] : 1'b0, reg_op1}) >>> reg_op2[4:0];
1225 end
1226 end endgenerate
1227
1228 always @* begin
1229 alu_out_0 = 'bx;
1230 (* parallel_case, full_case *)
1231 case (1'b1)
1232 instr_beq:
1233 alu_out_0 = alu_eq;
1234 instr_bne:
1235 alu_out_0 = !alu_eq;
1236 instr_bge:
1237 alu_out_0 = !alu_lts;
1238 instr_bgeu:
1239 alu_out_0 = !alu_ltu;
1240 is_slti_blt_slt && (!TWO_CYCLE_COMPARE || !{instr_beq,instr_bne,instr_bge,instr_bgeu}):
1241 alu_out_0 = alu_lts;
1242 is_sltiu_bltu_sltu && (!TWO_CYCLE_COMPARE || !{instr_beq,instr_bne,instr_bge,instr_bgeu}):
1243 alu_out_0 = alu_ltu;
1244 endcase
1245
1246 alu_out = 'bx;
1247 (* parallel_case, full_case *)
1248 case (1'b1)
1249 is_lui_auipc_jal_jalr_addi_add_sub:
1250 alu_out = alu_add_sub;
1251 is_compare:
1252 alu_out = alu_out_0;
1253 instr_xori || instr_xor:
1254 alu_out = reg_op1 ^ reg_op2;
1255 instr_ori || instr_or:
1256 alu_out = reg_op1 | reg_op2;
1257 instr_andi || instr_and:
1258 alu_out = reg_op1 & reg_op2;
1259 BARREL_SHIFTER && (instr_sll || instr_slli):
1260 alu_out = alu_shl;
1261 BARREL_SHIFTER && (instr_srl || instr_srli || instr_sra || instr_srai):
1262 alu_out = alu_shr;
1263 endcase
1264
1265`ifdef RISCV_FORMAL_BLACKBOX_ALU
1266 alu_out_0 = $anyseq;
1267 alu_out = $anyseq;
1268`endif
1269 end
1270
1271 reg clear_prefetched_high_word_q;
1272 always @(posedge clk) clear_prefetched_high_word_q <= clear_prefetched_high_word;
1273
1274 always @* begin
1275 clear_prefetched_high_word = clear_prefetched_high_word_q;
1276 if (!prefetched_high_word)
1277 clear_prefetched_high_word = 0;
1278 if (latched_branch || irq_state || !resetn)
1279 clear_prefetched_high_word = COMPRESSED_ISA;
1280 end
1281
1282 reg cpuregs_write;
1283 reg [31:0] cpuregs_wrdata;
1284 reg [31:0] cpuregs_rs1;
1285 reg [31:0] cpuregs_rs2;
1286 reg [regindex_bits-1:0] decoded_rs;
1287
1288 always @* begin
1289 cpuregs_write = 0;
1290 cpuregs_wrdata = 'bx;
1291
1292 if (cpu_state == cpu_state_fetch) begin
1293 (* parallel_case *)
1294 case (1'b1)
1295 latched_branch: begin
1296 cpuregs_wrdata = reg_pc + (latched_compr ? 2 : 4);
1297 cpuregs_write = 1;
1298 end
1299 latched_store && !latched_branch: begin
1300 cpuregs_wrdata = latched_stalu ? alu_out_q : reg_out;
1301 cpuregs_write = 1;
1302 end
1303 ENABLE_IRQ && irq_state[0]: begin
1304 cpuregs_wrdata = reg_next_pc | latched_compr;
1305 cpuregs_write = 1;
1306 end
1307 ENABLE_IRQ && irq_state[1]: begin
1308 cpuregs_wrdata = irq_pending & ~irq_mask;
1309 cpuregs_write = 1;
1310 end
1311 endcase
1312 end
1313 end
1314
1315`ifndef PICORV32_REGS
1316 always @(posedge clk) begin
1317 if (resetn && cpuregs_write && latched_rd)
1318 cpuregs[latched_rd] <= cpuregs_wrdata;
1319 end
1320
1321 always @* begin
1322 decoded_rs = 'bx;
1323 if (ENABLE_REGS_DUALPORT) begin
1324`ifndef RISCV_FORMAL_BLACKBOX_REGS
1325 cpuregs_rs1 = decoded_rs1 ? cpuregs[decoded_rs1] : 0;
1326 cpuregs_rs2 = decoded_rs2 ? cpuregs[decoded_rs2] : 0;
1327`else
1328 cpuregs_rs1 = decoded_rs1 ? $anyseq : 0;
1329 cpuregs_rs2 = decoded_rs2 ? $anyseq : 0;
1330`endif
1331 end else begin
1332 decoded_rs = (cpu_state == cpu_state_ld_rs2) ? decoded_rs2 : decoded_rs1;
1333`ifndef RISCV_FORMAL_BLACKBOX_REGS
1334 cpuregs_rs1 = decoded_rs ? cpuregs[decoded_rs] : 0;
1335`else
1336 cpuregs_rs1 = decoded_rs ? $anyseq : 0;
1337`endif
1338 cpuregs_rs2 = cpuregs_rs1;
1339 end
1340 end
1341`else
1342 wire[31:0] cpuregs_rdata1;
1343 wire[31:0] cpuregs_rdata2;
1344
1345 wire [5:0] cpuregs_waddr = latched_rd;
1346 wire [5:0] cpuregs_raddr1 = ENABLE_REGS_DUALPORT ? decoded_rs1 : decoded_rs;
1347 wire [5:0] cpuregs_raddr2 = ENABLE_REGS_DUALPORT ? decoded_rs2 : 0;
1348
1349 `PICORV32_REGS cpuregs (
1350 .clk(clk),
1351 .wen(resetn && cpuregs_write && latched_rd),
1352 .waddr(cpuregs_waddr),
1353 .raddr1(cpuregs_raddr1),
1354 .raddr2(cpuregs_raddr2),
1355 .wdata(cpuregs_wrdata),
1356 .rdata1(cpuregs_rdata1),
1357 .rdata2(cpuregs_rdata2)
1358 );
1359
1360 always @* begin
1361 decoded_rs = 'bx;
1362 if (ENABLE_REGS_DUALPORT) begin
1363 cpuregs_rs1 = decoded_rs1 ? cpuregs_rdata1 : 0;
1364 cpuregs_rs2 = decoded_rs2 ? cpuregs_rdata2 : 0;
1365 end else begin
1366 decoded_rs = (cpu_state == cpu_state_ld_rs2) ? decoded_rs2 : decoded_rs1;
1367 cpuregs_rs1 = decoded_rs ? cpuregs_rdata1 : 0;
1368 cpuregs_rs2 = cpuregs_rs1;
1369 end
1370 end
1371`endif
1372
1373 assign launch_next_insn = cpu_state == cpu_state_fetch && decoder_trigger && (!ENABLE_IRQ || irq_delay || irq_active || !(irq_pending & ~irq_mask));
1374
1375 always @(posedge clk) begin
1376 trap <= 0;
1377 reg_sh <= 'bx;
1378 reg_out <= 'bx;
1379 set_mem_do_rinst = 0;
1380 set_mem_do_rdata = 0;
1381 set_mem_do_wdata = 0;
1382
1383 alu_out_0_q <= alu_out_0;
1384 alu_out_q <= alu_out;
1385
1386 alu_wait <= 0;
1387 alu_wait_2 <= 0;
1388
1389 if (launch_next_insn) begin
1390 dbg_rs1val <= 'bx;
1391 dbg_rs2val <= 'bx;
1392 dbg_rs1val_valid <= 0;
1393 dbg_rs2val_valid <= 0;
1394 end
1395
1396 if (WITH_PCPI && CATCH_ILLINSN) begin
1397 if (resetn && pcpi_valid && !pcpi_int_wait) begin
1398 if (pcpi_timeout_counter)
1399 pcpi_timeout_counter <= pcpi_timeout_counter - 1;
1400 end else
1401 pcpi_timeout_counter <= ~0;
1402 pcpi_timeout <= !pcpi_timeout_counter;
1403 end
1404
1405 if (ENABLE_COUNTERS) begin
1406 count_cycle <= resetn ? count_cycle + 1 : 0;
1407 if (!ENABLE_COUNTERS64) count_cycle[63:32] <= 0;
1408 end else begin
1409 count_cycle <= 'bx;
1410 count_instr <= 'bx;
1411 end
1412
1413 next_irq_pending = ENABLE_IRQ ? irq_pending & LATCHED_IRQ : 'bx;
1414
1415 if (ENABLE_IRQ && ENABLE_IRQ_TIMER && timer) begin
1416 if (timer - 1 == 0)
1417 next_irq_pending[irq_timer] = 1;
1418 timer <= timer - 1;
1419 end
1420
1421 if (ENABLE_IRQ) begin
1422 next_irq_pending = next_irq_pending | irq;
1423 end
1424
1425 decoder_trigger <= mem_do_rinst && mem_done;
1426 decoder_trigger_q <= decoder_trigger;
1427 decoder_pseudo_trigger <= 0;
1428 decoder_pseudo_trigger_q <= decoder_pseudo_trigger;
1429 do_waitirq <= 0;
1430
1431 trace_valid <= 0;
1432
1433 if (!ENABLE_TRACE)
1434 trace_data <= 'bx;
1435
1436 if (!resetn) begin
1437 reg_pc <= PROGADDR_RESET;
1438 reg_next_pc <= PROGADDR_RESET;
1439 if (ENABLE_COUNTERS)
1440 count_instr <= 0;
1441 latched_store <= 0;
1442 latched_stalu <= 0;
1443 latched_branch <= 0;
1444 latched_trace <= 0;
1445 latched_is_lu <= 0;
1446 latched_is_lh <= 0;
1447 latched_is_lb <= 0;
1448 pcpi_valid <= 0;
1449 pcpi_timeout <= 0;
1450 irq_active <= 0;
1451 irq_delay <= 0;
1452 irq_mask <= ~0;
1453 next_irq_pending = 0;
1454 irq_state <= 0;
1455 eoi <= 0;
1456 timer <= 0;
1457 if (~STACKADDR) begin
1458 latched_store <= 1;
1459 latched_rd <= 2;
1460 reg_out <= STACKADDR;
1461 end
1462 cpu_state <= cpu_state_fetch;
1463 end else
1464 (* parallel_case, full_case *)
1465 case (cpu_state)
1466 cpu_state_trap: begin
1467 trap <= 1;
1468 end
1469
1470 cpu_state_fetch: begin
1471 mem_do_rinst <= !decoder_trigger && !do_waitirq;
1472 mem_wordsize <= 0;
1473
1474 current_pc = reg_next_pc;
1475
1476 (* parallel_case *)
1477 case (1'b1)
1478 latched_branch: begin
1479 current_pc = latched_store ? (latched_stalu ? alu_out_q : reg_out) & ~1 : reg_next_pc;
1480 `debug($display("ST_RD: %2d 0x%08x, BRANCH 0x%08x", latched_rd, reg_pc + (latched_compr ? 2 : 4), current_pc);)
1481 end
1482 latched_store && !latched_branch: begin
1483 `debug($display("ST_RD: %2d 0x%08x", latched_rd, latched_stalu ? alu_out_q : reg_out);)
1484 end
1485 ENABLE_IRQ && irq_state[0]: begin
1486 current_pc = PROGADDR_IRQ;
1487 irq_active <= 1;
1488 mem_do_rinst <= 1;
1489 end
1490 ENABLE_IRQ && irq_state[1]: begin
1491 eoi <= irq_pending & ~irq_mask;
1492 next_irq_pending = next_irq_pending & irq_mask;
1493 end
1494 endcase
1495
1496 if (ENABLE_TRACE && latched_trace) begin
1497 latched_trace <= 0;
1498 trace_valid <= 1;
1499 if (latched_branch)
1500 trace_data <= (irq_active ? TRACE_IRQ : 0) | TRACE_BRANCH | (current_pc & 32'hfffffffe);
1501 else
1502 trace_data <= (irq_active ? TRACE_IRQ : 0) | (latched_stalu ? alu_out_q : reg_out);
1503 end
1504
1505 reg_pc <= current_pc;
1506 reg_next_pc <= current_pc;
1507
1508 latched_store <= 0;
1509 latched_stalu <= 0;
1510 latched_branch <= 0;
1511 latched_is_lu <= 0;
1512 latched_is_lh <= 0;
1513 latched_is_lb <= 0;
1514 latched_rd <= decoded_rd;
1515 latched_compr <= compressed_instr;
1516
1517 if (ENABLE_IRQ && ((decoder_trigger && !irq_active && !irq_delay && |(irq_pending & ~irq_mask)) || irq_state)) begin
1518 irq_state <=
1519 irq_state == 2'b00 ? 2'b01 :
1520 irq_state == 2'b01 ? 2'b10 : 2'b00;
1521 latched_compr <= latched_compr;
1522 if (ENABLE_IRQ_QREGS)
1523 latched_rd <= irqregs_offset | irq_state[0];
1524 else
1525 latched_rd <= irq_state[0] ? 4 : 3;
1526 end else
1527 if (ENABLE_IRQ && (decoder_trigger || do_waitirq) && instr_waitirq) begin
1528 if (irq_pending) begin
1529 latched_store <= 1;
1530 reg_out <= irq_pending;
1531 reg_next_pc <= current_pc + (compressed_instr ? 2 : 4);
1532 mem_do_rinst <= 1;
1533 end else
1534 do_waitirq <= 1;
1535 end else
1536 if (decoder_trigger) begin
1537 `debug($display("-- %-0t", $time);)
1538 irq_delay <= irq_active;
1539 reg_next_pc <= current_pc + (compressed_instr ? 2 : 4);
1540 if (ENABLE_TRACE)
1541 latched_trace <= 1;
1542 if (ENABLE_COUNTERS) begin
1543 count_instr <= count_instr + 1;
1544 if (!ENABLE_COUNTERS64) count_instr[63:32] <= 0;
1545 end
1546 if (instr_jal) begin
1547 mem_do_rinst <= 1;
1548 reg_next_pc <= current_pc + decoded_imm_uj;
1549 latched_branch <= 1;
1550 end else begin
1551 mem_do_rinst <= 0;
1552 mem_do_prefetch <= !instr_jalr && !instr_retirq;
1553 cpu_state <= cpu_state_ld_rs1;
1554 end
1555 end
1556 end
1557
1558 cpu_state_ld_rs1: begin
1559 reg_op1 <= 'bx;
1560 reg_op2 <= 'bx;
1561
1562 (* parallel_case *)
1563 case (1'b1)
1564 (CATCH_ILLINSN || WITH_PCPI) && instr_trap: begin
1565 if (WITH_PCPI) begin
1566 `debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);)
1567 reg_op1 <= cpuregs_rs1;
1568 dbg_rs1val <= cpuregs_rs1;
1569 dbg_rs1val_valid <= 1;
1570 if (ENABLE_REGS_DUALPORT) begin
1571 pcpi_valid <= 1;
1572 `debug($display("LD_RS2: %2d 0x%08x", decoded_rs2, cpuregs_rs2);)
1573 reg_sh <= cpuregs_rs2;
1574 reg_op2 <= cpuregs_rs2;
1575 dbg_rs2val <= cpuregs_rs2;
1576 dbg_rs2val_valid <= 1;
1577 if (pcpi_int_ready) begin
1578 mem_do_rinst <= 1;
1579 pcpi_valid <= 0;
1580 reg_out <= pcpi_int_rd;
1581 latched_store <= pcpi_int_wr;
1582 cpu_state <= cpu_state_fetch;
1583 end else
1584 if (CATCH_ILLINSN && (pcpi_timeout || instr_ecall_ebreak)) begin
1585 pcpi_valid <= 0;
1586 `debug($display("EBREAK OR UNSUPPORTED INSN AT 0x%08x", reg_pc);)
1587 if (ENABLE_IRQ && !irq_mask[irq_ebreak] && !irq_active) begin
1588 next_irq_pending[irq_ebreak] = 1;
1589 cpu_state <= cpu_state_fetch;
1590 end else
1591 cpu_state <= cpu_state_trap;
1592 end
1593 end else begin
1594 cpu_state <= cpu_state_ld_rs2;
1595 end
1596 end else begin
1597 `debug($display("EBREAK OR UNSUPPORTED INSN AT 0x%08x", reg_pc);)
1598 if (ENABLE_IRQ && !irq_mask[irq_ebreak] && !irq_active) begin
1599 next_irq_pending[irq_ebreak] = 1;
1600 cpu_state <= cpu_state_fetch;
1601 end else
1602 cpu_state <= cpu_state_trap;
1603 end
1604 end
1605 ENABLE_COUNTERS && is_rdcycle_rdcycleh_rdinstr_rdinstrh: begin
1606 (* parallel_case, full_case *)
1607 case (1'b1)
1608 instr_rdcycle:
1609 reg_out <= count_cycle[31:0];
1610 instr_rdcycleh && ENABLE_COUNTERS64:
1611 reg_out <= count_cycle[63:32];
1612 instr_rdinstr:
1613 reg_out <= count_instr[31:0];
1614 instr_rdinstrh && ENABLE_COUNTERS64:
1615 reg_out <= count_instr[63:32];
1616 endcase
1617 latched_store <= 1;
1618 cpu_state <= cpu_state_fetch;
1619 end
1620 is_lui_auipc_jal: begin
1621 reg_op1 <= instr_lui ? 0 : reg_pc;
1622 reg_op2 <= decoded_imm;
1623 if (TWO_CYCLE_ALU)
1624 alu_wait <= 1;
1625 else
1626 mem_do_rinst <= mem_do_prefetch;
1627 cpu_state <= cpu_state_exec;
1628 end
1629 ENABLE_IRQ && ENABLE_IRQ_QREGS && instr_getq: begin
1630 `debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);)
1631 reg_out <= cpuregs_rs1;
1632 dbg_rs1val <= cpuregs_rs1;
1633 dbg_rs1val_valid <= 1;
1634 latched_store <= 1;
1635 cpu_state <= cpu_state_fetch;
1636 end
1637 ENABLE_IRQ && ENABLE_IRQ_QREGS && instr_setq: begin
1638 `debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);)
1639 reg_out <= cpuregs_rs1;
1640 dbg_rs1val <= cpuregs_rs1;
1641 dbg_rs1val_valid <= 1;
1642 latched_rd <= latched_rd | irqregs_offset;
1643 latched_store <= 1;
1644 cpu_state <= cpu_state_fetch;
1645 end
1646 ENABLE_IRQ && instr_retirq: begin
1647 eoi <= 0;
1648 irq_active <= 0;
1649 latched_branch <= 1;
1650 latched_store <= 1;
1651 `debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);)
1652 reg_out <= CATCH_MISALIGN ? (cpuregs_rs1 & 32'h fffffffe) : cpuregs_rs1;
1653 dbg_rs1val <= cpuregs_rs1;
1654 dbg_rs1val_valid <= 1;
1655 cpu_state <= cpu_state_fetch;
1656 end
1657 ENABLE_IRQ && instr_maskirq: begin
1658 latched_store <= 1;
1659 reg_out <= irq_mask;
1660 `debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);)
1661 irq_mask <= cpuregs_rs1 | MASKED_IRQ;
1662 dbg_rs1val <= cpuregs_rs1;
1663 dbg_rs1val_valid <= 1;
1664 cpu_state <= cpu_state_fetch;
1665 end
1666 ENABLE_IRQ && ENABLE_IRQ_TIMER && instr_timer: begin
1667 latched_store <= 1;
1668 reg_out <= timer;
1669 `debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);)
1670 timer <= cpuregs_rs1;
1671 dbg_rs1val <= cpuregs_rs1;
1672 dbg_rs1val_valid <= 1;
1673 cpu_state <= cpu_state_fetch;
1674 end
1675 is_lb_lh_lw_lbu_lhu && !instr_trap: begin
1676 `debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);)
1677 reg_op1 <= cpuregs_rs1;
1678 dbg_rs1val <= cpuregs_rs1;
1679 dbg_rs1val_valid <= 1;
1680 cpu_state <= cpu_state_ldmem;
1681 mem_do_rinst <= 1;
1682 end
1683 is_slli_srli_srai && !BARREL_SHIFTER: begin
1684 `debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);)
1685 reg_op1 <= cpuregs_rs1;
1686 dbg_rs1val <= cpuregs_rs1;
1687 dbg_rs1val_valid <= 1;
1688 reg_sh <= decoded_rs2;
1689 cpu_state <= cpu_state_shift;
1690 end
1691 is_jalr_addi_slti_sltiu_xori_ori_andi, is_slli_srli_srai && BARREL_SHIFTER: begin
1692 `debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);)
1693 reg_op1 <= cpuregs_rs1;
1694 dbg_rs1val <= cpuregs_rs1;
1695 dbg_rs1val_valid <= 1;
1696 reg_op2 <= is_slli_srli_srai && BARREL_SHIFTER ? decoded_rs2 : decoded_imm;
1697 if (TWO_CYCLE_ALU)
1698 alu_wait <= 1;
1699 else
1700 mem_do_rinst <= mem_do_prefetch;
1701 cpu_state <= cpu_state_exec;
1702 end
1703 default: begin
1704 `debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);)
1705 reg_op1 <= cpuregs_rs1;
1706 dbg_rs1val <= cpuregs_rs1;
1707 dbg_rs1val_valid <= 1;
1708 if (ENABLE_REGS_DUALPORT) begin
1709 `debug($display("LD_RS2: %2d 0x%08x", decoded_rs2, cpuregs_rs2);)
1710 reg_sh <= cpuregs_rs2;
1711 reg_op2 <= cpuregs_rs2;
1712 dbg_rs2val <= cpuregs_rs2;
1713 dbg_rs2val_valid <= 1;
1714 (* parallel_case *)
1715 case (1'b1)
1716 is_sb_sh_sw: begin
1717 cpu_state <= cpu_state_stmem;
1718 mem_do_rinst <= 1;
1719 end
1720 is_sll_srl_sra && !BARREL_SHIFTER: begin
1721 cpu_state <= cpu_state_shift;
1722 end
1723 default: begin
1724 if (TWO_CYCLE_ALU || (TWO_CYCLE_COMPARE && is_beq_bne_blt_bge_bltu_bgeu)) begin
1725 alu_wait_2 <= TWO_CYCLE_ALU && (TWO_CYCLE_COMPARE && is_beq_bne_blt_bge_bltu_bgeu);
1726 alu_wait <= 1;
1727 end else
1728 mem_do_rinst <= mem_do_prefetch;
1729 cpu_state <= cpu_state_exec;
1730 end
1731 endcase
1732 end else
1733 cpu_state <= cpu_state_ld_rs2;
1734 end
1735 endcase
1736 end
1737
1738 cpu_state_ld_rs2: begin
1739 `debug($display("LD_RS2: %2d 0x%08x", decoded_rs2, cpuregs_rs2);)
1740 reg_sh <= cpuregs_rs2;
1741 reg_op2 <= cpuregs_rs2;
1742 dbg_rs2val <= cpuregs_rs2;
1743 dbg_rs2val_valid <= 1;
1744
1745 (* parallel_case *)
1746 case (1'b1)
1747 WITH_PCPI && instr_trap: begin
1748 pcpi_valid <= 1;
1749 if (pcpi_int_ready) begin
1750 mem_do_rinst <= 1;
1751 pcpi_valid <= 0;
1752 reg_out <= pcpi_int_rd;
1753 latched_store <= pcpi_int_wr;
1754 cpu_state <= cpu_state_fetch;
1755 end else
1756 if (CATCH_ILLINSN && (pcpi_timeout || instr_ecall_ebreak)) begin
1757 pcpi_valid <= 0;
1758 `debug($display("EBREAK OR UNSUPPORTED INSN AT 0x%08x", reg_pc);)
1759 if (ENABLE_IRQ && !irq_mask[irq_ebreak] && !irq_active) begin
1760 next_irq_pending[irq_ebreak] = 1;
1761 cpu_state <= cpu_state_fetch;
1762 end else
1763 cpu_state <= cpu_state_trap;
1764 end
1765 end
1766 is_sb_sh_sw: begin
1767 cpu_state <= cpu_state_stmem;
1768 mem_do_rinst <= 1;
1769 end
1770 is_sll_srl_sra && !BARREL_SHIFTER: begin
1771 cpu_state <= cpu_state_shift;
1772 end
1773 default: begin
1774 if (TWO_CYCLE_ALU || (TWO_CYCLE_COMPARE && is_beq_bne_blt_bge_bltu_bgeu)) begin
1775 alu_wait_2 <= TWO_CYCLE_ALU && (TWO_CYCLE_COMPARE && is_beq_bne_blt_bge_bltu_bgeu);
1776 alu_wait <= 1;
1777 end else
1778 mem_do_rinst <= mem_do_prefetch;
1779 cpu_state <= cpu_state_exec;
1780 end
1781 endcase
1782 end
1783
1784 cpu_state_exec: begin
1785 reg_out <= reg_pc + decoded_imm;
1786 if ((TWO_CYCLE_ALU || TWO_CYCLE_COMPARE) && (alu_wait || alu_wait_2)) begin
1787 mem_do_rinst <= mem_do_prefetch && !alu_wait_2;
1788 alu_wait <= alu_wait_2;
1789 end else
1790 if (is_beq_bne_blt_bge_bltu_bgeu) begin
1791 latched_rd <= 0;
1792 latched_store <= TWO_CYCLE_COMPARE ? alu_out_0_q : alu_out_0;
1793 latched_branch <= TWO_CYCLE_COMPARE ? alu_out_0_q : alu_out_0;
1794 if (mem_done)
1795 cpu_state <= cpu_state_fetch;
1796 if (TWO_CYCLE_COMPARE ? alu_out_0_q : alu_out_0) begin
1797 decoder_trigger <= 0;
1798 set_mem_do_rinst = 1;
1799 end
1800 end else begin
1801 latched_branch <= instr_jalr;
1802 latched_store <= 1;
1803 latched_stalu <= 1;
1804 cpu_state <= cpu_state_fetch;
1805 end
1806 end
1807
1808 cpu_state_shift: begin
1809 latched_store <= 1;
1810 if (reg_sh == 0) begin
1811 reg_out <= reg_op1;
1812 mem_do_rinst <= mem_do_prefetch;
1813 cpu_state <= cpu_state_fetch;
1814 end else if (TWO_STAGE_SHIFT && reg_sh >= 4) begin
1815 (* parallel_case, full_case *)
1816 case (1'b1)
1817 instr_slli || instr_sll: reg_op1 <= reg_op1 << 4;
1818 instr_srli || instr_srl: reg_op1 <= reg_op1 >> 4;
1819 instr_srai || instr_sra: reg_op1 <= $signed(reg_op1) >>> 4;
1820 endcase
1821 reg_sh <= reg_sh - 4;
1822 end else begin
1823 (* parallel_case, full_case *)
1824 case (1'b1)
1825 instr_slli || instr_sll: reg_op1 <= reg_op1 << 1;
1826 instr_srli || instr_srl: reg_op1 <= reg_op1 >> 1;
1827 instr_srai || instr_sra: reg_op1 <= $signed(reg_op1) >>> 1;
1828 endcase
1829 reg_sh <= reg_sh - 1;
1830 end
1831 end
1832
1833 cpu_state_stmem: begin
1834 if (ENABLE_TRACE)
1835 reg_out <= reg_op2;
1836 if (!mem_do_prefetch || mem_done) begin
1837 if (!mem_do_wdata) begin
1838 (* parallel_case, full_case *)
1839 case (1'b1)
1840 instr_sb: mem_wordsize <= 2;
1841 instr_sh: mem_wordsize <= 1;
1842 instr_sw: mem_wordsize <= 0;
1843 endcase
1844 if (ENABLE_TRACE) begin
1845 trace_valid <= 1;
1846 trace_data <= (irq_active ? TRACE_IRQ : 0) | TRACE_ADDR | ((reg_op1 + decoded_imm) & 32'hffffffff);
1847 end
1848 reg_op1 <= reg_op1 + decoded_imm;
1849 set_mem_do_wdata = 1;
1850 end
1851 if (!mem_do_prefetch && mem_done) begin
1852 cpu_state <= cpu_state_fetch;
1853 decoder_trigger <= 1;
1854 decoder_pseudo_trigger <= 1;
1855 end
1856 end
1857 end
1858
1859 cpu_state_ldmem: begin
1860 latched_store <= 1;
1861 if (!mem_do_prefetch || mem_done) begin
1862 if (!mem_do_rdata) begin
1863 (* parallel_case, full_case *)
1864 case (1'b1)
1865 instr_lb || instr_lbu: mem_wordsize <= 2;
1866 instr_lh || instr_lhu: mem_wordsize <= 1;
1867 instr_lw: mem_wordsize <= 0;
1868 endcase
1869 latched_is_lu <= is_lbu_lhu_lw;
1870 latched_is_lh <= instr_lh;
1871 latched_is_lb <= instr_lb;
1872 if (ENABLE_TRACE) begin
1873 trace_valid <= 1;
1874 trace_data <= (irq_active ? TRACE_IRQ : 0) | TRACE_ADDR | ((reg_op1 + decoded_imm) & 32'hffffffff);
1875 end
1876 reg_op1 <= reg_op1 + decoded_imm;
1877 set_mem_do_rdata = 1;
1878 end
1879 if (!mem_do_prefetch && mem_done) begin
1880 (* parallel_case, full_case *)
1881 case (1'b1)
1882 latched_is_lu: reg_out <= mem_rdata_word;
1883 latched_is_lh: reg_out <= $signed(mem_rdata_word[15:0]);
1884 latched_is_lb: reg_out <= $signed(mem_rdata_word[7:0]);
1885 endcase
1886 decoder_trigger <= 1;
1887 decoder_pseudo_trigger <= 1;
1888 cpu_state <= cpu_state_fetch;
1889 end
1890 end
1891 end
1892 endcase
1893
1894 if (CATCH_MISALIGN && resetn && (mem_do_rdata || mem_do_wdata)) begin
1895 if (mem_wordsize == 0 && reg_op1[1:0] != 0) begin
1896 `debug($display("MISALIGNED WORD: 0x%08x", reg_op1);)
1897 if (ENABLE_IRQ && !irq_mask[irq_buserror] && !irq_active) begin
1898 next_irq_pending[irq_buserror] = 1;
1899 end else
1900 cpu_state <= cpu_state_trap;
1901 end
1902 if (mem_wordsize == 1 && reg_op1[0] != 0) begin
1903 `debug($display("MISALIGNED HALFWORD: 0x%08x", reg_op1);)
1904 if (ENABLE_IRQ && !irq_mask[irq_buserror] && !irq_active) begin
1905 next_irq_pending[irq_buserror] = 1;
1906 end else
1907 cpu_state <= cpu_state_trap;
1908 end
1909 end
1910 if (CATCH_MISALIGN && resetn && mem_do_rinst && (COMPRESSED_ISA ? reg_pc[0] : |reg_pc[1:0])) begin
1911 `debug($display("MISALIGNED INSTRUCTION: 0x%08x", reg_pc);)
1912 if (ENABLE_IRQ && !irq_mask[irq_buserror] && !irq_active) begin
1913 next_irq_pending[irq_buserror] = 1;
1914 end else
1915 cpu_state <= cpu_state_trap;
1916 end
1917 if (!CATCH_ILLINSN && decoder_trigger_q && !decoder_pseudo_trigger_q && instr_ecall_ebreak) begin
1918 cpu_state <= cpu_state_trap;
1919 end
1920
1921 if (!resetn || mem_done) begin
1922 mem_do_prefetch <= 0;
1923 mem_do_rinst <= 0;
1924 mem_do_rdata <= 0;
1925 mem_do_wdata <= 0;
1926 end
1927
1928 if (set_mem_do_rinst)
1929 mem_do_rinst <= 1;
1930 if (set_mem_do_rdata)
1931 mem_do_rdata <= 1;
1932 if (set_mem_do_wdata)
1933 mem_do_wdata <= 1;
1934
1935 irq_pending <= next_irq_pending & ~MASKED_IRQ;
1936
1937 if (!CATCH_MISALIGN) begin
1938 if (COMPRESSED_ISA) begin
1939 reg_pc[0] <= 0;
1940 reg_next_pc[0] <= 0;
1941 end else begin
1942 reg_pc[1:0] <= 0;
1943 reg_next_pc[1:0] <= 0;
1944 end
1945 end
1946 current_pc = 'bx;
1947 end
1948
1949`ifdef RISCV_FORMAL
1950 reg dbg_irq_call;
1951 reg dbg_irq_enter;
1952 reg [31:0] dbg_irq_ret;
1953 always @(posedge clk) begin
1954 rvfi_valid <= resetn && (launch_next_insn || trap) && dbg_valid_insn;
1955 rvfi_order <= resetn ? rvfi_order + rvfi_valid : 0;
1956
1957 rvfi_insn <= dbg_insn_opcode;
1958 rvfi_rs1_addr <= dbg_rs1val_valid ? dbg_insn_rs1 : 0;
1959 rvfi_rs2_addr <= dbg_rs2val_valid ? dbg_insn_rs2 : 0;
1960 rvfi_pc_rdata <= dbg_insn_addr;
1961 rvfi_rs1_rdata <= dbg_rs1val_valid ? dbg_rs1val : 0;
1962 rvfi_rs2_rdata <= dbg_rs2val_valid ? dbg_rs2val : 0;
1963 rvfi_trap <= trap;
1964 rvfi_halt <= trap;
1965 rvfi_intr <= dbg_irq_enter;
1966 rvfi_mode <= 3;
1967
1968 if (!resetn) begin
1969 dbg_irq_call <= 0;
1970 dbg_irq_enter <= 0;
1971 end else
1972 if (rvfi_valid) begin
1973 dbg_irq_call <= 0;
1974 dbg_irq_enter <= dbg_irq_call;
1975 end else
1976 if (irq_state == 1) begin
1977 dbg_irq_call <= 1;
1978 dbg_irq_ret <= next_pc;
1979 end
1980
1981 if (!resetn) begin
1982 rvfi_rd_addr <= 0;
1983 rvfi_rd_wdata <= 0;
1984 end else
1985 if (cpuregs_write && !irq_state) begin
1986 rvfi_rd_addr <= latched_rd;
1987 rvfi_rd_wdata <= latched_rd ? cpuregs_wrdata : 0;
1988 end else
1989 if (rvfi_valid) begin
1990 rvfi_rd_addr <= 0;
1991 rvfi_rd_wdata <= 0;
1992 end
1993
1994 casez (dbg_insn_opcode)
1995 32'b 0000000_?????_000??_???_?????_0001011: begin // getq
1996 rvfi_rs1_addr <= 0;
1997 rvfi_rs1_rdata <= 0;
1998 end
1999 32'b 0000001_?????_?????_???_000??_0001011: begin // setq
2000 rvfi_rd_addr <= 0;
2001 rvfi_rd_wdata <= 0;
2002 end
2003 32'b 0000010_?????_00000_???_00000_0001011: begin // retirq
2004 rvfi_rs1_addr <= 0;
2005 rvfi_rs1_rdata <= 0;
2006 end
2007 endcase
2008
2009 if (!dbg_irq_call) begin
2010 if (dbg_mem_instr) begin
2011 rvfi_mem_addr <= 0;
2012 rvfi_mem_rmask <= 0;
2013 rvfi_mem_wmask <= 0;
2014 rvfi_mem_rdata <= 0;
2015 rvfi_mem_wdata <= 0;
2016 end else
2017 if (dbg_mem_valid && dbg_mem_ready) begin
2018 rvfi_mem_addr <= dbg_mem_addr;
2019 rvfi_mem_rmask <= dbg_mem_wstrb ? 0 : ~0;
2020 rvfi_mem_wmask <= dbg_mem_wstrb;
2021 rvfi_mem_rdata <= dbg_mem_rdata;
2022 rvfi_mem_wdata <= dbg_mem_wdata;
2023 end
2024 end
2025 end
2026
2027 always @* begin
2028 rvfi_pc_wdata = dbg_irq_call ? dbg_irq_ret : dbg_insn_addr;
2029 end
2030`endif
2031
2032 // Formal Verification
2033`ifdef FORMAL
2034 reg [3:0] last_mem_nowait;
2035 always @(posedge clk)
2036 last_mem_nowait <= {last_mem_nowait, mem_ready || !mem_valid};
2037
2038 // stall the memory interface for max 4 cycles
2039 restrict property (|last_mem_nowait || mem_ready || !mem_valid);
2040
2041 // resetn low in first cycle, after that resetn high
2042 restrict property (resetn != $initstate);
2043
2044 // this just makes it much easier to read traces. uncomment as needed.
2045 // assume property (mem_valid || !mem_ready);
2046
2047 reg ok;
2048 always @* begin
2049 if (resetn) begin
2050 // instruction fetches are read-only
2051 if (mem_valid && mem_instr)
2052 assert (mem_wstrb == 0);
2053
2054 // cpu_state must be valid
2055 ok = 0;
2056 if (cpu_state == cpu_state_trap) ok = 1;
2057 if (cpu_state == cpu_state_fetch) ok = 1;
2058 if (cpu_state == cpu_state_ld_rs1) ok = 1;
2059 if (cpu_state == cpu_state_ld_rs2) ok = !ENABLE_REGS_DUALPORT;
2060 if (cpu_state == cpu_state_exec) ok = 1;
2061 if (cpu_state == cpu_state_shift) ok = 1;
2062 if (cpu_state == cpu_state_stmem) ok = 1;
2063 if (cpu_state == cpu_state_ldmem) ok = 1;
2064 assert (ok);
2065 end
2066 end
2067
2068 reg last_mem_la_read = 0;
2069 reg last_mem_la_write = 0;
2070 reg [31:0] last_mem_la_addr;
2071 reg [31:0] last_mem_la_wdata;
2072 reg [3:0] last_mem_la_wstrb = 0;
2073
2074 always @(posedge clk) begin
2075 last_mem_la_read <= mem_la_read;
2076 last_mem_la_write <= mem_la_write;
2077 last_mem_la_addr <= mem_la_addr;
2078 last_mem_la_wdata <= mem_la_wdata;
2079 last_mem_la_wstrb <= mem_la_wstrb;
2080
2081 if (last_mem_la_read) begin
2082 assert(mem_valid);
2083 assert(mem_addr == last_mem_la_addr);
2084 assert(mem_wstrb == 0);
2085 end
2086 if (last_mem_la_write) begin
2087 assert(mem_valid);
2088 assert(mem_addr == last_mem_la_addr);
2089 assert(mem_wdata == last_mem_la_wdata);
2090 assert(mem_wstrb == last_mem_la_wstrb);
2091 end
2092 if (mem_la_read || mem_la_write) begin
2093 assert(!mem_valid || mem_ready);
2094 end
2095 end
2096`endif
2097endmodule
2098
2099// This is a simple example implementation of PICORV32_REGS.
2100// Use the PICORV32_REGS mechanism if you want to use custom
2101// memory resources to implement the processor register file.
2102// Note that your implementation must match the requirements of
2103// the PicoRV32 configuration. (e.g. QREGS, etc)
2104module picorv32_regs (
2105 input clk, wen,
2106 input [5:0] waddr,
2107 input [5:0] raddr1,
2108 input [5:0] raddr2,
2109 input [31:0] wdata,
2110 output [31:0] rdata1,
2111 output [31:0] rdata2
2112);
2113 reg [31:0] regs [0:30];
2114
2115 always @(posedge clk)
2116 if (wen) regs[~waddr[4:0]] <= wdata;
2117
2118 assign rdata1 = regs[~raddr1[4:0]];
2119 assign rdata2 = regs[~raddr2[4:0]];
2120endmodule
2121
2122
2123/***************************************************************
2124 * picorv32_pcpi_mul
2125 ***************************************************************/
2126
2127module picorv32_pcpi_mul #(
2128 parameter STEPS_AT_ONCE = 1,
2129 parameter CARRY_CHAIN = 4
2130) (
2131 input clk, resetn,
2132
2133 input pcpi_valid,
2134 input [31:0] pcpi_insn,
2135 input [31:0] pcpi_rs1,
2136 input [31:0] pcpi_rs2,
2137 output reg pcpi_wr,
2138 output reg [31:0] pcpi_rd,
2139 output reg pcpi_wait,
2140 output reg pcpi_ready
2141);
2142 reg instr_mul, instr_mulh, instr_mulhsu, instr_mulhu;
2143 wire instr_any_mul = |{instr_mul, instr_mulh, instr_mulhsu, instr_mulhu};
2144 wire instr_any_mulh = |{instr_mulh, instr_mulhsu, instr_mulhu};
2145 wire instr_rs1_signed = |{instr_mulh, instr_mulhsu};
2146 wire instr_rs2_signed = |{instr_mulh};
2147
2148 reg pcpi_wait_q;
2149 wire mul_start = pcpi_wait && !pcpi_wait_q;
2150
2151 always @(posedge clk) begin
2152 instr_mul <= 0;
2153 instr_mulh <= 0;
2154 instr_mulhsu <= 0;
2155 instr_mulhu <= 0;
2156
2157 if (resetn && pcpi_valid && pcpi_insn[6:0] == 7'b0110011 && pcpi_insn[31:25] == 7'b0000001) begin
2158 case (pcpi_insn[14:12])
2159 3'b000: instr_mul <= 1;
2160 3'b001: instr_mulh <= 1;
2161 3'b010: instr_mulhsu <= 1;
2162 3'b011: instr_mulhu <= 1;
2163 endcase
2164 end
2165
2166 pcpi_wait <= instr_any_mul;
2167 pcpi_wait_q <= pcpi_wait;
2168 end
2169
2170 reg [63:0] rs1, rs2, rd, rdx;
2171 reg [63:0] next_rs1, next_rs2, this_rs2;
2172 reg [63:0] next_rd, next_rdx, next_rdt;
2173 reg [6:0] mul_counter;
2174 reg mul_waiting;
2175 reg mul_finish;
2176 integer i, j;
2177
2178 // carry save accumulator
2179 always @* begin
2180 next_rd = rd;
2181 next_rdx = rdx;
2182 next_rs1 = rs1;
2183 next_rs2 = rs2;
2184
2185 for (i = 0; i < STEPS_AT_ONCE; i=i+1) begin
2186 this_rs2 = next_rs1[0] ? next_rs2 : 0;
2187 if (CARRY_CHAIN == 0) begin
2188 next_rdt = next_rd ^ next_rdx ^ this_rs2;
2189 next_rdx = ((next_rd & next_rdx) | (next_rd & this_rs2) | (next_rdx & this_rs2)) << 1;
2190 next_rd = next_rdt;
2191 end else begin
2192 next_rdt = 0;
2193 for (j = 0; j < 64; j = j + CARRY_CHAIN)
2194 {next_rdt[j+CARRY_CHAIN-1], next_rd[j +: CARRY_CHAIN]} =
2195 next_rd[j +: CARRY_CHAIN] + next_rdx[j +: CARRY_CHAIN] + this_rs2[j +: CARRY_CHAIN];
2196 next_rdx = next_rdt << 1;
2197 end
2198 next_rs1 = next_rs1 >> 1;
2199 next_rs2 = next_rs2 << 1;
2200 end
2201 end
2202
2203 always @(posedge clk) begin
2204 mul_finish <= 0;
2205 if (!resetn) begin
2206 mul_waiting <= 1;
2207 end else
2208 if (mul_waiting) begin
2209 if (instr_rs1_signed)
2210 rs1 <= $signed(pcpi_rs1);
2211 else
2212 rs1 <= $unsigned(pcpi_rs1);
2213
2214 if (instr_rs2_signed)
2215 rs2 <= $signed(pcpi_rs2);
2216 else
2217 rs2 <= $unsigned(pcpi_rs2);
2218
2219 rd <= 0;
2220 rdx <= 0;
2221 mul_counter <= (instr_any_mulh ? 63 - STEPS_AT_ONCE : 31 - STEPS_AT_ONCE);
2222 mul_waiting <= !mul_start;
2223 end else begin
2224 rd <= next_rd;
2225 rdx <= next_rdx;
2226 rs1 <= next_rs1;
2227 rs2 <= next_rs2;
2228
2229 mul_counter <= mul_counter - STEPS_AT_ONCE;
2230 if (mul_counter[6]) begin
2231 mul_finish <= 1;
2232 mul_waiting <= 1;
2233 end
2234 end
2235 end
2236
2237 always @(posedge clk) begin
2238 pcpi_wr <= 0;
2239 pcpi_ready <= 0;
2240 if (mul_finish && resetn) begin
2241 pcpi_wr <= 1;
2242 pcpi_ready <= 1;
2243 pcpi_rd <= instr_any_mulh ? rd >> 32 : rd;
2244 end
2245 end
2246endmodule
2247
2248module picorv32_pcpi_fast_mul #(
2249 parameter EXTRA_MUL_FFS = 0,
2250 parameter EXTRA_INSN_FFS = 0,
2251 parameter MUL_CLKGATE = 0
2252) (
2253 input clk, resetn,
2254
2255 input pcpi_valid,
2256 input [31:0] pcpi_insn,
2257 input [31:0] pcpi_rs1,
2258 input [31:0] pcpi_rs2,
2259 output pcpi_wr,
2260 output [31:0] pcpi_rd,
2261 output pcpi_wait,
2262 output pcpi_ready
2263);
2264 reg instr_mul, instr_mulh, instr_mulhsu, instr_mulhu;
2265 wire instr_any_mul = |{instr_mul, instr_mulh, instr_mulhsu, instr_mulhu};
2266 wire instr_any_mulh = |{instr_mulh, instr_mulhsu, instr_mulhu};
2267 wire instr_rs1_signed = |{instr_mulh, instr_mulhsu};
2268 wire instr_rs2_signed = |{instr_mulh};
2269
2270 reg shift_out;
2271 reg [3:0] active;
2272 reg [32:0] rs1, rs2, rs1_q, rs2_q;
2273 reg [63:0] rd, rd_q;
2274
2275 wire pcpi_insn_valid = pcpi_valid && pcpi_insn[6:0] == 7'b0110011 && pcpi_insn[31:25] == 7'b0000001;
2276 reg pcpi_insn_valid_q;
2277
2278 always @* begin
2279 instr_mul = 0;
2280 instr_mulh = 0;
2281 instr_mulhsu = 0;
2282 instr_mulhu = 0;
2283
2284 if (resetn && (EXTRA_INSN_FFS ? pcpi_insn_valid_q : pcpi_insn_valid)) begin
2285 case (pcpi_insn[14:12])
2286 3'b000: instr_mul = 1;
2287 3'b001: instr_mulh = 1;
2288 3'b010: instr_mulhsu = 1;
2289 3'b011: instr_mulhu = 1;
2290 endcase
2291 end
2292 end
2293
2294 always @(posedge clk) begin
2295 pcpi_insn_valid_q <= pcpi_insn_valid;
2296 if (!MUL_CLKGATE || active[0]) begin
2297 rs1_q <= rs1;
2298 rs2_q <= rs2;
2299 end
2300 if (!MUL_CLKGATE || active[1]) begin
2301 rd <= $signed(EXTRA_MUL_FFS ? rs1_q : rs1) * $signed(EXTRA_MUL_FFS ? rs2_q : rs2);
2302 end
2303 if (!MUL_CLKGATE || active[2]) begin
2304 rd_q <= rd;
2305 end
2306 end
2307
2308 always @(posedge clk) begin
2309 if (instr_any_mul && !(EXTRA_MUL_FFS ? active[3:0] : active[1:0])) begin
2310 if (instr_rs1_signed)
2311 rs1 <= $signed(pcpi_rs1);
2312 else
2313 rs1 <= $unsigned(pcpi_rs1);
2314
2315 if (instr_rs2_signed)
2316 rs2 <= $signed(pcpi_rs2);
2317 else
2318 rs2 <= $unsigned(pcpi_rs2);
2319 active[0] <= 1;
2320 end else begin
2321 active[0] <= 0;
2322 end
2323
2324 active[3:1] <= active;
2325 shift_out <= instr_any_mulh;
2326
2327 if (!resetn)
2328 active <= 0;
2329 end
2330
2331 assign pcpi_wr = active[EXTRA_MUL_FFS ? 3 : 1];
2332 assign pcpi_wait = 0;
2333 assign pcpi_ready = active[EXTRA_MUL_FFS ? 3 : 1];
2334`ifdef RISCV_FORMAL_ALTOPS
2335 assign pcpi_rd =
2336 instr_mul ? (pcpi_rs1 + pcpi_rs2) ^ 32'h5876063e :
2337 instr_mulh ? (pcpi_rs1 + pcpi_rs2) ^ 32'hf6583fb7 :
2338 instr_mulhsu ? (pcpi_rs1 - pcpi_rs2) ^ 32'hecfbe137 :
2339 instr_mulhu ? (pcpi_rs1 + pcpi_rs2) ^ 32'h949ce5e8 : 1'bx;
2340`else
2341 assign pcpi_rd = shift_out ? (EXTRA_MUL_FFS ? rd_q : rd) >> 32 : (EXTRA_MUL_FFS ? rd_q : rd);
2342`endif
2343endmodule
2344
2345
2346/***************************************************************
2347 * picorv32_pcpi_div
2348 ***************************************************************/
2349
2350module picorv32_pcpi_div (
2351 input clk, resetn,
2352
2353 input pcpi_valid,
2354 input [31:0] pcpi_insn,
2355 input [31:0] pcpi_rs1,
2356 input [31:0] pcpi_rs2,
2357 output reg pcpi_wr,
2358 output reg [31:0] pcpi_rd,
2359 output reg pcpi_wait,
2360 output reg pcpi_ready
2361);
2362 reg instr_div, instr_divu, instr_rem, instr_remu;
2363 wire instr_any_div_rem = |{instr_div, instr_divu, instr_rem, instr_remu};
2364
2365 reg pcpi_wait_q;
2366 wire start = pcpi_wait && !pcpi_wait_q;
2367
2368 always @(posedge clk) begin
2369 instr_div <= 0;
2370 instr_divu <= 0;
2371 instr_rem <= 0;
2372 instr_remu <= 0;
2373
2374 if (resetn && pcpi_valid && !pcpi_ready && pcpi_insn[6:0] == 7'b0110011 && pcpi_insn[31:25] == 7'b0000001) begin
2375 case (pcpi_insn[14:12])
2376 3'b100: instr_div <= 1;
2377 3'b101: instr_divu <= 1;
2378 3'b110: instr_rem <= 1;
2379 3'b111: instr_remu <= 1;
2380 endcase
2381 end
2382
2383 pcpi_wait <= instr_any_div_rem && resetn;
2384 pcpi_wait_q <= pcpi_wait && resetn;
2385 end
2386
2387 reg [31:0] dividend;
2388 reg [62:0] divisor;
2389 reg [31:0] quotient;
2390 reg [31:0] quotient_msk;
2391 reg running;
2392 reg outsign;
2393
2394 always @(posedge clk) begin
2395 pcpi_ready <= 0;
2396 pcpi_wr <= 0;
2397 pcpi_rd <= 'bx;
2398
2399 if (!resetn) begin
2400 running <= 0;
2401 end else
2402 if (start) begin
2403 running <= 1;
2404 dividend <= (instr_div || instr_rem) && pcpi_rs1[31] ? -pcpi_rs1 : pcpi_rs1;
2405 divisor <= ((instr_div || instr_rem) && pcpi_rs2[31] ? -pcpi_rs2 : pcpi_rs2) << 31;
2406 outsign <= (instr_div && (pcpi_rs1[31] != pcpi_rs2[31]) && |pcpi_rs2) || (instr_rem && pcpi_rs1[31]);
2407 quotient <= 0;
2408 quotient_msk <= 1 << 31;
2409 end else
2410 if (!quotient_msk && running) begin
2411 running <= 0;
2412 pcpi_ready <= 1;
2413 pcpi_wr <= 1;
2414`ifdef RISCV_FORMAL_ALTOPS
2415 case (1)
2416 instr_div: pcpi_rd <= (pcpi_rs1 - pcpi_rs2) ^ 32'h7f8529ec;
2417 instr_divu: pcpi_rd <= (pcpi_rs1 - pcpi_rs2) ^ 32'h10e8fd70;
2418 instr_rem: pcpi_rd <= (pcpi_rs1 - pcpi_rs2) ^ 32'h8da68fa5;
2419 instr_remu: pcpi_rd <= (pcpi_rs1 - pcpi_rs2) ^ 32'h3138d0e1;
2420 endcase
2421`else
2422 if (instr_div || instr_divu)
2423 pcpi_rd <= outsign ? -quotient : quotient;
2424 else
2425 pcpi_rd <= outsign ? -dividend : dividend;
2426`endif
2427 end else begin
2428 if (divisor <= dividend) begin
2429 dividend <= dividend - divisor;
2430 quotient <= quotient | quotient_msk;
2431 end
2432 divisor <= divisor >> 1;
2433`ifdef RISCV_FORMAL_ALTOPS
2434 quotient_msk <= quotient_msk >> 5;
2435`else
2436 quotient_msk <= quotient_msk >> 1;
2437`endif
2438 end
2439 end
2440endmodule
2441
2442
2443/***************************************************************
2444 * picorv32_axi
2445 ***************************************************************/
2446
2447module picorv32_axi #(
2448 parameter [ 0:0] ENABLE_COUNTERS = 1,
2449 parameter [ 0:0] ENABLE_COUNTERS64 = 1,
2450 parameter [ 0:0] ENABLE_REGS_16_31 = 1,
2451 parameter [ 0:0] ENABLE_REGS_DUALPORT = 1,
2452 parameter [ 0:0] TWO_STAGE_SHIFT = 1,
2453 parameter [ 0:0] BARREL_SHIFTER = 0,
2454 parameter [ 0:0] TWO_CYCLE_COMPARE = 0,
2455 parameter [ 0:0] TWO_CYCLE_ALU = 0,
2456 parameter [ 0:0] COMPRESSED_ISA = 0,
2457 parameter [ 0:0] CATCH_MISALIGN = 1,
2458 parameter [ 0:0] CATCH_ILLINSN = 1,
2459 parameter [ 0:0] ENABLE_PCPI = 0,
2460 parameter [ 0:0] ENABLE_MUL = 0,
2461 parameter [ 0:0] ENABLE_FAST_MUL = 0,
2462 parameter [ 0:0] ENABLE_DIV = 0,
2463 parameter [ 0:0] ENABLE_IRQ = 0,
2464 parameter [ 0:0] ENABLE_IRQ_QREGS = 1,
2465 parameter [ 0:0] ENABLE_IRQ_TIMER = 1,
2466 parameter [ 0:0] ENABLE_TRACE = 0,
2467 parameter [ 0:0] REGS_INIT_ZERO = 0,
2468 parameter [31:0] MASKED_IRQ = 32'h 0000_0000,
2469 parameter [31:0] LATCHED_IRQ = 32'h ffff_ffff,
2470 parameter [31:0] PROGADDR_RESET = 32'h 0000_0000,
2471 parameter [31:0] PROGADDR_IRQ = 32'h 0000_0010,
2472 parameter [31:0] STACKADDR = 32'h ffff_ffff
2473) (
2474 input clk, resetn,
2475 output trap,
2476
2477 // AXI4-lite master memory interface
2478
2479 output mem_axi_awvalid,
2480 input mem_axi_awready,
2481 output [31:0] mem_axi_awaddr,
2482 output [ 2:0] mem_axi_awprot,
2483
2484 output mem_axi_wvalid,
2485 input mem_axi_wready,
2486 output [31:0] mem_axi_wdata,
2487 output [ 3:0] mem_axi_wstrb,
2488
2489 input mem_axi_bvalid,
2490 output mem_axi_bready,
2491
2492 output mem_axi_arvalid,
2493 input mem_axi_arready,
2494 output [31:0] mem_axi_araddr,
2495 output [ 2:0] mem_axi_arprot,
2496
2497 input mem_axi_rvalid,
2498 output mem_axi_rready,
2499 input [31:0] mem_axi_rdata,
2500
2501 // Pico Co-Processor Interface (PCPI)
2502 output pcpi_valid,
2503 output [31:0] pcpi_insn,
2504 output [31:0] pcpi_rs1,
2505 output [31:0] pcpi_rs2,
2506 input pcpi_wr,
2507 input [31:0] pcpi_rd,
2508 input pcpi_wait,
2509 input pcpi_ready,
2510
2511 // IRQ interface
2512 input [31:0] irq,
2513 output [31:0] eoi,
2514
2515`ifdef RISCV_FORMAL
2516 output rvfi_valid,
2517 output [63:0] rvfi_order,
2518 output [31:0] rvfi_insn,
2519 output rvfi_trap,
2520 output rvfi_halt,
2521 output rvfi_intr,
2522 output [ 4:0] rvfi_rs1_addr,
2523 output [ 4:0] rvfi_rs2_addr,
2524 output [31:0] rvfi_rs1_rdata,
2525 output [31:0] rvfi_rs2_rdata,
2526 output [ 4:0] rvfi_rd_addr,
2527 output [31:0] rvfi_rd_wdata,
2528 output [31:0] rvfi_pc_rdata,
2529 output [31:0] rvfi_pc_wdata,
2530 output [31:0] rvfi_mem_addr,
2531 output [ 3:0] rvfi_mem_rmask,
2532 output [ 3:0] rvfi_mem_wmask,
2533 output [31:0] rvfi_mem_rdata,
2534 output [31:0] rvfi_mem_wdata,
2535`endif
2536
2537 // Trace Interface
2538 output trace_valid,
2539 output [35:0] trace_data
2540);
2541 wire mem_valid;
2542 wire [31:0] mem_addr;
2543 wire [31:0] mem_wdata;
2544 wire [ 3:0] mem_wstrb;
2545 wire mem_instr;
2546 wire mem_ready;
2547 wire [31:0] mem_rdata;
2548
2549 picorv32_axi_adapter axi_adapter (
2550 .clk (clk ),
2551 .resetn (resetn ),
2552 .mem_axi_awvalid(mem_axi_awvalid),
2553 .mem_axi_awready(mem_axi_awready),
2554 .mem_axi_awaddr (mem_axi_awaddr ),
2555 .mem_axi_awprot (mem_axi_awprot ),
2556 .mem_axi_wvalid (mem_axi_wvalid ),
2557 .mem_axi_wready (mem_axi_wready ),
2558 .mem_axi_wdata (mem_axi_wdata ),
2559 .mem_axi_wstrb (mem_axi_wstrb ),
2560 .mem_axi_bvalid (mem_axi_bvalid ),
2561 .mem_axi_bready (mem_axi_bready ),
2562 .mem_axi_arvalid(mem_axi_arvalid),
2563 .mem_axi_arready(mem_axi_arready),
2564 .mem_axi_araddr (mem_axi_araddr ),
2565 .mem_axi_arprot (mem_axi_arprot ),
2566 .mem_axi_rvalid (mem_axi_rvalid ),
2567 .mem_axi_rready (mem_axi_rready ),
2568 .mem_axi_rdata (mem_axi_rdata ),
2569 .mem_valid (mem_valid ),
2570 .mem_instr (mem_instr ),
2571 .mem_ready (mem_ready ),
2572 .mem_addr (mem_addr ),
2573 .mem_wdata (mem_wdata ),
2574 .mem_wstrb (mem_wstrb ),
2575 .mem_rdata (mem_rdata )
2576 );
2577
2578 picorv32 #(
2579 .ENABLE_COUNTERS (ENABLE_COUNTERS ),
2580 .ENABLE_COUNTERS64 (ENABLE_COUNTERS64 ),
2581 .ENABLE_REGS_16_31 (ENABLE_REGS_16_31 ),
2582 .ENABLE_REGS_DUALPORT(ENABLE_REGS_DUALPORT),
2583 .TWO_STAGE_SHIFT (TWO_STAGE_SHIFT ),
2584 .BARREL_SHIFTER (BARREL_SHIFTER ),
2585 .TWO_CYCLE_COMPARE (TWO_CYCLE_COMPARE ),
2586 .TWO_CYCLE_ALU (TWO_CYCLE_ALU ),
2587 .COMPRESSED_ISA (COMPRESSED_ISA ),
2588 .CATCH_MISALIGN (CATCH_MISALIGN ),
2589 .CATCH_ILLINSN (CATCH_ILLINSN ),
2590 .ENABLE_PCPI (ENABLE_PCPI ),
2591 .ENABLE_MUL (ENABLE_MUL ),
2592 .ENABLE_FAST_MUL (ENABLE_FAST_MUL ),
2593 .ENABLE_DIV (ENABLE_DIV ),
2594 .ENABLE_IRQ (ENABLE_IRQ ),
2595 .ENABLE_IRQ_QREGS (ENABLE_IRQ_QREGS ),
2596 .ENABLE_IRQ_TIMER (ENABLE_IRQ_TIMER ),
2597 .ENABLE_TRACE (ENABLE_TRACE ),
2598 .REGS_INIT_ZERO (REGS_INIT_ZERO ),
2599 .MASKED_IRQ (MASKED_IRQ ),
2600 .LATCHED_IRQ (LATCHED_IRQ ),
2601 .PROGADDR_RESET (PROGADDR_RESET ),
2602 .PROGADDR_IRQ (PROGADDR_IRQ ),
2603 .STACKADDR (STACKADDR )
2604 ) picorv32_core (
2605 .clk (clk ),
2606 .resetn (resetn),
2607 .trap (trap ),
2608
2609 .mem_valid(mem_valid),
2610 .mem_addr (mem_addr ),
2611 .mem_wdata(mem_wdata),
2612 .mem_wstrb(mem_wstrb),
2613 .mem_instr(mem_instr),
2614 .mem_ready(mem_ready),
2615 .mem_rdata(mem_rdata),
2616
2617 .pcpi_valid(pcpi_valid),
2618 .pcpi_insn (pcpi_insn ),
2619 .pcpi_rs1 (pcpi_rs1 ),
2620 .pcpi_rs2 (pcpi_rs2 ),
2621 .pcpi_wr (pcpi_wr ),
2622 .pcpi_rd (pcpi_rd ),
2623 .pcpi_wait (pcpi_wait ),
2624 .pcpi_ready(pcpi_ready),
2625
2626 .irq(irq),
2627 .eoi(eoi),
2628
2629`ifdef RISCV_FORMAL
2630 .rvfi_valid (rvfi_valid ),
2631 .rvfi_order (rvfi_order ),
2632 .rvfi_insn (rvfi_insn ),
2633 .rvfi_trap (rvfi_trap ),
2634 .rvfi_halt (rvfi_halt ),
2635 .rvfi_intr (rvfi_intr ),
2636 .rvfi_rs1_addr (rvfi_rs1_addr ),
2637 .rvfi_rs2_addr (rvfi_rs2_addr ),
2638 .rvfi_rs1_rdata(rvfi_rs1_rdata),
2639 .rvfi_rs2_rdata(rvfi_rs2_rdata),
2640 .rvfi_rd_addr (rvfi_rd_addr ),
2641 .rvfi_rd_wdata (rvfi_rd_wdata ),
2642 .rvfi_pc_rdata (rvfi_pc_rdata ),
2643 .rvfi_pc_wdata (rvfi_pc_wdata ),
2644 .rvfi_mem_addr (rvfi_mem_addr ),
2645 .rvfi_mem_rmask(rvfi_mem_rmask),
2646 .rvfi_mem_wmask(rvfi_mem_wmask),
2647 .rvfi_mem_rdata(rvfi_mem_rdata),
2648 .rvfi_mem_wdata(rvfi_mem_wdata),
2649`endif
2650
2651 .trace_valid(trace_valid),
2652 .trace_data (trace_data)
2653 );
2654endmodule
2655
2656
2657/***************************************************************
2658 * picorv32_axi_adapter
2659 ***************************************************************/
2660
2661module picorv32_axi_adapter (
2662 input clk, resetn,
2663
2664 // AXI4-lite master memory interface
2665
2666 output mem_axi_awvalid,
2667 input mem_axi_awready,
2668 output [31:0] mem_axi_awaddr,
2669 output [ 2:0] mem_axi_awprot,
2670
2671 output mem_axi_wvalid,
2672 input mem_axi_wready,
2673 output [31:0] mem_axi_wdata,
2674 output [ 3:0] mem_axi_wstrb,
2675
2676 input mem_axi_bvalid,
2677 output mem_axi_bready,
2678
2679 output mem_axi_arvalid,
2680 input mem_axi_arready,
2681 output [31:0] mem_axi_araddr,
2682 output [ 2:0] mem_axi_arprot,
2683
2684 input mem_axi_rvalid,
2685 output mem_axi_rready,
2686 input [31:0] mem_axi_rdata,
2687
2688 // Native PicoRV32 memory interface
2689
2690 input mem_valid,
2691 input mem_instr,
2692 output mem_ready,
2693 input [31:0] mem_addr,
2694 input [31:0] mem_wdata,
2695 input [ 3:0] mem_wstrb,
2696 output [31:0] mem_rdata
2697);
2698 reg ack_awvalid;
2699 reg ack_arvalid;
2700 reg ack_wvalid;
2701 reg xfer_done;
2702
2703 assign mem_axi_awvalid = mem_valid && |mem_wstrb && !ack_awvalid;
2704 assign mem_axi_awaddr = mem_addr;
2705 assign mem_axi_awprot = 0;
2706
2707 assign mem_axi_arvalid = mem_valid && !mem_wstrb && !ack_arvalid;
2708 assign mem_axi_araddr = mem_addr;
2709 assign mem_axi_arprot = mem_instr ? 3'b100 : 3'b000;
2710
2711 assign mem_axi_wvalid = mem_valid && |mem_wstrb && !ack_wvalid;
2712 assign mem_axi_wdata = mem_wdata;
2713 assign mem_axi_wstrb = mem_wstrb;
2714
2715 assign mem_ready = mem_axi_bvalid || mem_axi_rvalid;
2716 assign mem_axi_bready = mem_valid && |mem_wstrb;
2717 assign mem_axi_rready = mem_valid && !mem_wstrb;
2718 assign mem_rdata = mem_axi_rdata;
2719
2720 always @(posedge clk) begin
2721 if (!resetn) begin
2722 ack_awvalid <= 0;
2723 end else begin
2724 xfer_done <= mem_valid && mem_ready;
2725 if (mem_axi_awready && mem_axi_awvalid)
2726 ack_awvalid <= 1;
2727 if (mem_axi_arready && mem_axi_arvalid)
2728 ack_arvalid <= 1;
2729 if (mem_axi_wready && mem_axi_wvalid)
2730 ack_wvalid <= 1;
2731 if (xfer_done || !mem_valid) begin
2732 ack_awvalid <= 0;
2733 ack_arvalid <= 0;
2734 ack_wvalid <= 0;
2735 end
2736 end
2737 end
2738endmodule
2739
2740
2741/***************************************************************
2742 * picorv32_wb
2743 ***************************************************************/
2744
2745module picorv32_wb #(
2746 parameter [ 0:0] ENABLE_COUNTERS = 1,
2747 parameter [ 0:0] ENABLE_COUNTERS64 = 1,
2748 parameter [ 0:0] ENABLE_REGS_16_31 = 1,
2749 parameter [ 0:0] ENABLE_REGS_DUALPORT = 1,
2750 parameter [ 0:0] TWO_STAGE_SHIFT = 1,
2751 parameter [ 0:0] BARREL_SHIFTER = 0,
2752 parameter [ 0:0] TWO_CYCLE_COMPARE = 0,
2753 parameter [ 0:0] TWO_CYCLE_ALU = 0,
2754 parameter [ 0:0] COMPRESSED_ISA = 0,
2755 parameter [ 0:0] CATCH_MISALIGN = 1,
2756 parameter [ 0:0] CATCH_ILLINSN = 1,
2757 parameter [ 0:0] ENABLE_PCPI = 0,
2758 parameter [ 0:0] ENABLE_MUL = 0,
2759 parameter [ 0:0] ENABLE_FAST_MUL = 0,
2760 parameter [ 0:0] ENABLE_DIV = 0,
2761 parameter [ 0:0] ENABLE_IRQ = 0,
2762 parameter [ 0:0] ENABLE_IRQ_QREGS = 1,
2763 parameter [ 0:0] ENABLE_IRQ_TIMER = 1,
2764 parameter [ 0:0] ENABLE_TRACE = 0,
2765 parameter [ 0:0] REGS_INIT_ZERO = 0,
2766 parameter [31:0] MASKED_IRQ = 32'h 0000_0000,
2767 parameter [31:0] LATCHED_IRQ = 32'h ffff_ffff,
2768 parameter [31:0] PROGADDR_RESET = 32'h 0000_0000,
2769 parameter [31:0] PROGADDR_IRQ = 32'h 0000_0010,
2770 parameter [31:0] STACKADDR = 32'h ffff_ffff
2771) (
2772 output trap,
2773
2774 // Wishbone interfaces
2775 input wb_rst_i,
2776 input wb_clk_i,
2777
2778 output reg [31:0] wbm_adr_o,
2779 output reg [31:0] wbm_dat_o,
2780 input [31:0] wbm_dat_i,
2781 output reg wbm_we_o,
2782 output reg [3:0] wbm_sel_o,
2783 output reg wbm_stb_o,
2784 input wbm_ack_i,
2785 output reg wbm_cyc_o,
2786
2787 // Pico Co-Processor Interface (PCPI)
2788 output pcpi_valid,
2789 output [31:0] pcpi_insn,
2790 output [31:0] pcpi_rs1,
2791 output [31:0] pcpi_rs2,
2792 input pcpi_wr,
2793 input [31:0] pcpi_rd,
2794 input pcpi_wait,
2795 input pcpi_ready,
2796
2797 // IRQ interface
2798 input [31:0] irq,
2799 output [31:0] eoi,
2800
2801`ifdef RISCV_FORMAL
2802 output rvfi_valid,
2803 output [63:0] rvfi_order,
2804 output [31:0] rvfi_insn,
2805 output rvfi_trap,
2806 output rvfi_halt,
2807 output rvfi_intr,
2808 output [ 4:0] rvfi_rs1_addr,
2809 output [ 4:0] rvfi_rs2_addr,
2810 output [31:0] rvfi_rs1_rdata,
2811 output [31:0] rvfi_rs2_rdata,
2812 output [ 4:0] rvfi_rd_addr,
2813 output [31:0] rvfi_rd_wdata,
2814 output [31:0] rvfi_pc_rdata,
2815 output [31:0] rvfi_pc_wdata,
2816 output [31:0] rvfi_mem_addr,
2817 output [ 3:0] rvfi_mem_rmask,
2818 output [ 3:0] rvfi_mem_wmask,
2819 output [31:0] rvfi_mem_rdata,
2820 output [31:0] rvfi_mem_wdata,
2821`endif
2822
2823 // Trace Interface
2824 output trace_valid,
2825 output [35:0] trace_data,
2826
2827 output mem_instr
2828);
2829 wire mem_valid;
2830 wire [31:0] mem_addr;
2831 wire [31:0] mem_wdata;
2832 wire [ 3:0] mem_wstrb;
2833 reg mem_ready;
2834 reg [31:0] mem_rdata;
2835
2836 wire clk;
2837 wire resetn;
2838
2839 assign clk = wb_clk_i;
2840 assign resetn = ~wb_rst_i;
2841
2842 picorv32 #(
2843 .ENABLE_COUNTERS (ENABLE_COUNTERS ),
2844 .ENABLE_COUNTERS64 (ENABLE_COUNTERS64 ),
2845 .ENABLE_REGS_16_31 (ENABLE_REGS_16_31 ),
2846 .ENABLE_REGS_DUALPORT(ENABLE_REGS_DUALPORT),
2847 .TWO_STAGE_SHIFT (TWO_STAGE_SHIFT ),
2848 .BARREL_SHIFTER (BARREL_SHIFTER ),
2849 .TWO_CYCLE_COMPARE (TWO_CYCLE_COMPARE ),
2850 .TWO_CYCLE_ALU (TWO_CYCLE_ALU ),
2851 .COMPRESSED_ISA (COMPRESSED_ISA ),
2852 .CATCH_MISALIGN (CATCH_MISALIGN ),
2853 .CATCH_ILLINSN (CATCH_ILLINSN ),
2854 .ENABLE_PCPI (ENABLE_PCPI ),
2855 .ENABLE_MUL (ENABLE_MUL ),
2856 .ENABLE_FAST_MUL (ENABLE_FAST_MUL ),
2857 .ENABLE_DIV (ENABLE_DIV ),
2858 .ENABLE_IRQ (ENABLE_IRQ ),
2859 .ENABLE_IRQ_QREGS (ENABLE_IRQ_QREGS ),
2860 .ENABLE_IRQ_TIMER (ENABLE_IRQ_TIMER ),
2861 .ENABLE_TRACE (ENABLE_TRACE ),
2862 .REGS_INIT_ZERO (REGS_INIT_ZERO ),
2863 .MASKED_IRQ (MASKED_IRQ ),
2864 .LATCHED_IRQ (LATCHED_IRQ ),
2865 .PROGADDR_RESET (PROGADDR_RESET ),
2866 .PROGADDR_IRQ (PROGADDR_IRQ ),
2867 .STACKADDR (STACKADDR )
2868 ) picorv32_core (
2869 .clk (clk ),
2870 .resetn (resetn),
2871 .trap (trap ),
2872
2873 .mem_valid(mem_valid),
2874 .mem_addr (mem_addr ),
2875 .mem_wdata(mem_wdata),
2876 .mem_wstrb(mem_wstrb),
2877 .mem_instr(mem_instr),
2878 .mem_ready(mem_ready),
2879 .mem_rdata(mem_rdata),
2880
2881 .pcpi_valid(pcpi_valid),
2882 .pcpi_insn (pcpi_insn ),
2883 .pcpi_rs1 (pcpi_rs1 ),
2884 .pcpi_rs2 (pcpi_rs2 ),
2885 .pcpi_wr (pcpi_wr ),
2886 .pcpi_rd (pcpi_rd ),
2887 .pcpi_wait (pcpi_wait ),
2888 .pcpi_ready(pcpi_ready),
2889
2890 .irq(irq),
2891 .eoi(eoi),
2892
2893`ifdef RISCV_FORMAL
2894 .rvfi_valid (rvfi_valid ),
2895 .rvfi_order (rvfi_order ),
2896 .rvfi_insn (rvfi_insn ),
2897 .rvfi_trap (rvfi_trap ),
2898 .rvfi_halt (rvfi_halt ),
2899 .rvfi_intr (rvfi_intr ),
2900 .rvfi_rs1_addr (rvfi_rs1_addr ),
2901 .rvfi_rs2_addr (rvfi_rs2_addr ),
2902 .rvfi_rs1_rdata(rvfi_rs1_rdata),
2903 .rvfi_rs2_rdata(rvfi_rs2_rdata),
2904 .rvfi_rd_addr (rvfi_rd_addr ),
2905 .rvfi_rd_wdata (rvfi_rd_wdata ),
2906 .rvfi_pc_rdata (rvfi_pc_rdata ),
2907 .rvfi_pc_wdata (rvfi_pc_wdata ),
2908 .rvfi_mem_addr (rvfi_mem_addr ),
2909 .rvfi_mem_rmask(rvfi_mem_rmask),
2910 .rvfi_mem_wmask(rvfi_mem_wmask),
2911 .rvfi_mem_rdata(rvfi_mem_rdata),
2912 .rvfi_mem_wdata(rvfi_mem_wdata),
2913`endif
2914
2915 .trace_valid(trace_valid),
2916 .trace_data (trace_data)
2917 );
2918
2919 localparam IDLE = 2'b00;
2920 localparam WBSTART = 2'b01;
2921 localparam WBEND = 2'b10;
2922
2923 reg [1:0] state;
2924
2925 wire we;
2926 assign we = (mem_wstrb[0] | mem_wstrb[1] | mem_wstrb[2] | mem_wstrb[3]);
2927
2928 always @(posedge wb_clk_i) begin
2929 if (wb_rst_i) begin
2930 wbm_adr_o <= 0;
2931 wbm_dat_o <= 0;
2932 wbm_we_o <= 0;
2933 wbm_sel_o <= 0;
2934 wbm_stb_o <= 0;
2935 wbm_cyc_o <= 0;
2936 state <= IDLE;
2937 end else begin
2938 case (state)
2939 IDLE: begin
2940 if (mem_valid) begin
2941 wbm_adr_o <= mem_addr;
2942 wbm_dat_o <= mem_wdata;
2943 wbm_we_o <= we;
2944 wbm_sel_o <= mem_wstrb;
2945
2946 wbm_stb_o <= 1'b1;
2947 wbm_cyc_o <= 1'b1;
2948 state <= WBSTART;
2949 end else begin
2950 mem_ready <= 1'b0;
2951
2952 wbm_stb_o <= 1'b0;
2953 wbm_cyc_o <= 1'b0;
2954 wbm_we_o <= 1'b0;
2955 end
2956 end
2957 WBSTART:begin
2958 if (wbm_ack_i) begin
2959 mem_rdata <= wbm_dat_i;
2960 mem_ready <= 1'b1;
2961
2962 state <= WBEND;
2963
2964 wbm_stb_o <= 1'b0;
2965 wbm_cyc_o <= 1'b0;
2966 wbm_we_o <= 1'b0;
2967 end
2968 end
2969 WBEND: begin
2970 mem_ready <= 1'b0;
2971
2972 state <= IDLE;
2973 end
2974 default:
2975 state <= IDLE;
2976 endcase
2977 end
2978 end
2979endmodule