Some cleanup; correctly decode 16-bit EBREAK

This commit is contained in:
Luke Wren 2021-06-03 20:03:43 +01:00
parent 5f8d217395
commit af684c4e82
7 changed files with 22 additions and 33 deletions

View File

@ -45,7 +45,7 @@ wire [W_REQ-1:0] gnt_onehot = req & ~deny;
reg [W_GNT-1:0] gnt_accum;
always @ (*) begin: encode
integer i;
reg [W_GNT:0] i;
gnt_accum = {W_GNT{1'b0}};
for (i = 0; i < W_REQ; i = i + 1) begin
gnt_accum = gnt_accum | ({W_GNT{gnt_onehot[i]}} & i[W_GNT-1:0]);

View File

@ -61,7 +61,6 @@ module hazard3_core #(
`include "hazard3_ops.vh"
wire d_stall;
wire x_stall;
wire m_stall;
@ -178,9 +177,7 @@ hazard3_decode #(
.x_jump_not_except (x_jump_not_except),
.d_starved (d_starved),
.d_stall (d_stall),
.x_stall (x_stall),
.f_jump_rdy (f_jump_rdy),
.f_jump_now (f_jump_now),
.f_jump_target (f_jump_target),
@ -200,7 +197,6 @@ hazard3_decode #(
.d_branchcond (d_branchcond),
.d_jump_offs (d_jump_offs),
.d_jump_is_regoffs (d_jump_is_regoffs),
.d_pc (d_pc),
.d_except (d_except)
);
@ -671,7 +667,7 @@ hazard3_regfile_1w2r #(
`elsif FORMAL
.RESET_REGS(1),
`else
.RESET_REGS(0),
.RESET_REGS(1),
`endif
.N_REGS(32),
.W_DATA(W_DATA)

View File

@ -798,9 +798,9 @@ hazard3_priority_encode #(
wire exception_req_any = except != EXCEPT_NONE;
wire [5:0] vector_sel =
exception_req_any || !irq_vector_enable ? 6'd0 :
standard_irq_active ? standard_irq_num :
external_irq_active ? 6'd16 + external_irq_num : 6'd0;
exception_req_any || !irq_vector_enable ? 6'd0 :
standard_irq_active ? {2'h0, standard_irq_num} :
external_irq_active ? {1'h0, external_irq_num} + 6'd16 : 6'd0;
assign trap_addr = except == EXCEPT_MRET ? mepc : mtvec | {24'h0, vector_sel, 2'h0};
assign trap_is_irq = !exception_req_any;

View File

@ -32,9 +32,7 @@ module hazard3_decode #(
output wire [W_ADDR-1:0] d_pc,
output wire d_starved,
output wire d_stall,
input wire x_stall,
input wire f_jump_rdy,
input wire f_jump_now,
input wire [W_ADDR-1:0] f_jump_target,
input wire x_jump_not_except,
@ -93,7 +91,7 @@ wire [31:0] d_imm_j = {{12{d_instr[31]}}, d_instr[19:12], d_instr[20], d_instr[3
// PC/CIR control
assign d_starved = ~|fd_cir_vld || fd_cir_vld[0] && d_instr_is_32bit;
assign d_stall = x_stall || d_starved;
wire d_stall = x_stall || d_starved;
assign df_cir_use =
d_starved || d_stall ? 2'h0 :
@ -150,10 +148,6 @@ always @ (posedge clk or negedge rst_n) begin
end
end
// If the current CIR is there due to locking, it is a jump which has already had primary effect.
wire jump_enable = !d_starved && !cir_lock_prev && !d_invalid;
always @ (*) begin
// JAL is major opcode 1101111,
// JALR is 1100111,
@ -265,6 +259,9 @@ always @ (*) begin
if (d_invalid && !d_starved)
d_except = EXCEPT_INSTR_ILLEGAL;
end
if (cir_lock_prev) begin
d_branchcond = BCOND_NEVER;
end
end
endmodule

View File

@ -248,10 +248,8 @@ assign jump_target_rdy = !mem_addr_hold;
// Instruction assembly yard
// buf_level is the number of valid halfwords in {hwbuf, cir}.
// cir_vld and hwbuf_vld are functions of this.
reg [1:0] buf_level;
reg [W_BUNDLE-1:0] hwbuf;
reg hwbuf_vld;
wire [W_DATA-1:0] fetch_data = fifo_empty ? mem_data : fifo_rdata;
wire fetch_data_vld = !fifo_empty || (mem_data_vld && ~|ctr_flush_pending);
@ -290,7 +288,6 @@ wire [1:0] buf_level_next =
always @ (posedge clk or negedge rst_n) begin
if (!rst_n) begin
buf_level <= 2'h0;
hwbuf_vld <= 1'b0;
cir_vld <= 2'h0;
end else begin
`ifdef FORMAL
@ -300,7 +297,6 @@ always @ (posedge clk or negedge rst_n) begin
`endif
// Update CIR flags
buf_level <= buf_level_next;
hwbuf_vld <= &buf_level_next;
if (!cir_lock)
cir_vld <= buf_level_next & ~(buf_level_next >> 1'b1);
// Update CIR contents

View File

@ -33,14 +33,14 @@ wire [31:0] imm_cb =
{{4{instr_in[12]}}, instr_in[6:5], instr_in[2], {25{1'b0}}};
generate
if (PASSTHROUGH) begin
if (PASSTHROUGH) begin: instr_passthrough
always @ (*) begin
instr_is_32bit = 1'b1;
instr_out = instr_in;
invalid = 1'b0;
end
end else begin
always @ (*) begin;
end else begin: instr_decompress
always @ (*) begin
if (instr_in[1:0] == 2'b11) begin
instr_is_32bit = 1'b1;
instr_out = instr_in;
@ -69,7 +69,7 @@ end else begin
end else begin
instr_out = RV_NOZ_LUI | (rd_l << RV_RD_LSB) | ({{15{instr_in[12]}}, instr_in[6:2]} << 12);
end
invalid = !{instr_in[12], instr_in[6:2]}; // RESERVED if imm == 0
invalid = ~|{instr_in[12], instr_in[6:2]}; // RESERVED if imm == 0
end
RV_C_SLLI: instr_out = RV_NOZ_SLLI | (rs1_l << RV_RD_LSB) | (rs1_l << RV_RS1_LSB) | imm_ci;
RV_C_SRAI: instr_out = RV_NOZ_SRAI | (rs1_s << RV_RD_LSB) | (rs1_s << RV_RS1_LSB) | imm_ci;
@ -80,25 +80,26 @@ end else begin
RV_C_XOR: instr_out = RV_NOZ_XOR | (rs1_s << RV_RD_LSB) | (rs1_s << RV_RS1_LSB) | (rs2_s << RV_RS2_LSB);
RV_C_SUB: instr_out = RV_NOZ_SUB | (rs1_s << RV_RD_LSB) | (rs1_s << RV_RS1_LSB) | (rs2_s << RV_RS2_LSB);
RV_C_ADD: begin
if (rs2_l) begin
if (|rs2_l) begin
instr_out = RV_NOZ_ADD | (rd_l << RV_RD_LSB) | (rs1_l << RV_RS1_LSB) | (rs2_l << RV_RS2_LSB);
end else begin // jalr
end else if (|rs1_l) begin // jalr
instr_out = RV_NOZ_JALR | (5'h1 << RV_RD_LSB) | (rs1_l << RV_RS1_LSB);
invalid = !rs1_l; // EBREAK; not supported!
end else begin // ebreak
instr_out = RV_NOZ_EBREAK;
end
end
RV_C_MV: begin
if (rs2_l) begin // mv
if (|rs2_l) begin // mv
instr_out = RV_NOZ_ADD | (rd_l << RV_RD_LSB) | (rs2_l << RV_RS2_LSB);
end else begin // jr
instr_out = RV_NOZ_JALR | (rs1_l << RV_RS1_LSB);
invalid = !rs1_l; // RESERVED
invalid = ~|rs1_l; // RESERVED
end
end
RV_C_LWSP: begin
instr_out = RV_NOZ_LW | (rd_l << RV_RD_LSB) | (5'h2 << RV_RS1_LSB)
| ({instr_in[3:2], instr_in[12], instr_in[6:4], 2'b00} << 20);
invalid = !rd_l; // RESERVED
invalid = ~|rd_l; // RESERVED
end
RV_C_SWSP: instr_out = RV_NOZ_SW | (rs2_l << RV_RS2_LSB) | (5'h2 << RV_RS1_LSB)
| ({instr_in[11:9], 2'b00} << 7) | ({instr_in[8:7], instr_in[12]} << 25);

View File

@ -64,12 +64,11 @@ end else if (RESET_REGS) begin: real_dualport_reset
integer i;
always @ (posedge clk or negedge rst_n) begin
if (!rst_n) begin
// It's best to ask nicely:
// synthesis please_on
for (i = 0; i < N_REGS; i = i + 1) begin
mem[i] <= {W_DATA{1'b0}};
end
// synthesis please_off
rdata1 <= {W_DATA{1'b0}};
rdata2 <= {W_DATA{1'b0}};
end else begin
if (wen) begin
mem[waddr] <= wdata;