Rewrite immediate decoding

This commit is contained in:
Olof Kindgren 2018-11-22 13:02:51 +01:00
parent 94c7dab38d
commit fa8def6e7a
2 changed files with 38 additions and 55 deletions

View file

@ -73,7 +73,7 @@ module serv_ctrl
.rst (i_rst),
.a (offset_a),
.b (i_offset),
.clr (i_cnt_done),
.clr (!i_en | (i_cnt_done & !i_pc_en)),
.q (pc_plus_offset),
.o_v ());

View file

@ -213,6 +213,12 @@ module serv_decode
reg [31:0] imm;
reg signbit;
reg [8:0] imm19_12_20;
reg imm7;
reg [5:0] imm30_25;
reg [4:0] imm24_20;
reg [4:0] imm11_7;
always @(posedge clk) begin
if (i_wb_en) begin
o_rf_rd_addr <= i_wb_rdt[11:7];
@ -222,11 +228,41 @@ module serv_decode
imm30 <= i_wb_rdt[30];
opcode <= i_wb_rdt[6:2];
imm <= i_wb_rdt;
signbit <= imm[31];
signbit <= i_wb_rdt[31];
end
if (cnt_done | go | i_mem_dbus_ack) begin
imm19_12_20 <= {imm[19:12],imm[20]};
imm7 <= imm[7];
imm30_25 <= imm[30:25];
imm24_20 <= imm[24:20];
imm11_7 <= imm[11:7];
end else begin
imm19_12_20 <= {m3 ? signbit : imm24_20[0], imm19_12_20[8:1]};
imm7 <= signbit;
imm30_25 <= {m2[1] ? imm7 : m2[0] ? signbit : imm19_12_20[0], imm30_25[5:1]};
imm24_20 <= {imm30_25[0], imm24_20[4:1]};
imm11_7 <= {imm30_25[0], imm11_7[4:1]};
end
end
wire utype = !opcode[4] & (opcode[2:0] == 3'b101);
wire sorbtype = opcode[3:0] == 4'b1000;
wire iorstype = (opcode == OP_OPIMM) | (opcode == OP_JALR) | (opcode == OP_LOAD) | (opcode == OP_STORE);
wire m1 = sorbtype;
wire [1:0] m2;
assign m2[1] = (opcode == OP_BRANCH);
assign m2[0] = iorstype;
wire m3 = opcode[4];
wire gate1 = (cnt == 0) & ((opcode == OP_BRANCH) | (opcode == OP_JAL));
wire gate12 = (cnt < 12) & utype;
wire o_imm = (!(gate1 | gate12) & (cnt_done ? signbit : m1 ? imm11_7[0] : imm24_20[0]));
assign o_op_b_source = (opcode == OP_OPIMM) ? OP_B_SOURCE_IMM :
(opcode == OP_BRANCH) ? OP_B_SOURCE_RS2 :
(opcode == OP_OP) ? OP_B_SOURCE_RS2 :
@ -253,34 +289,6 @@ module serv_decode
(opcode == OP_SYSTEM) ? RD_SOURCE_CSR :
RD_SOURCE_MEM;
//31, cnt, 20, +20, +7, 7, 1'b0
wire imm_j =
(cnt > 19) ? imm[31] :
(cnt > 11) ? imm[cnt] :
(cnt > 10) ? imm[20] :
(cnt > 0) ? imm[cnt+20] :
1'b0;
wire imm_i = (cnt > 10) ? imm[31] : imm[cnt+20];
wire imm_u = (cnt > 11) ? imm[cnt] : 1'b0;
wire imm_b =
(cnt > 11) ? imm[31]:
(cnt > 10) ? imm[7] :
(cnt > 4) ? imm[cnt+20] :
(cnt > 0) ? imm[cnt+7] : 1'b0;
wire imm_s =
(cnt > 10) ? imm[31] :
(cnt > 4) ? imm[cnt+20] :
imm[cnt+7];
wire o_imm =
(opcode == OP_JAL) ? imm_j :
((opcode == OP_OPIMM) | (opcode == OP_JALR) | (opcode == OP_LOAD)) ? imm_i :
((opcode == OP_LUI) | (opcode == OP_AUIPC)) ? imm_u :
(opcode == OP_BRANCH) ? imm_b :
(opcode == OP_STORE) ? imm_s : 1'b0;
always @(posedge clk) begin
go <= i_wb_en;
if (i_rst)
@ -341,33 +349,8 @@ module serv_decode
cnt <= cnt + {4'd0,cnt_en};
if (i_rst) begin
//output reg [2:0] o_funct3,
//output reg o_imm,
state <= IDLE;
cnt <= 5'd0;
//reg imm30;
//reg [4:0] opcode;
//reg [31:0] imm;
end
end
//`define SERV_DECODE_CHECKS
`ifdef SERV_DECODE_CHECKS
reg unknown_op = 1'b0;
always @(opcode)
if (i_wb_en) begin
if (!((opcode == OP_LOAD) |
(opcode == OP_STORE ) |
(opcode == OP_OPIMM ) |
(opcode == OP_AUIPC ) |
(opcode == OP_OP ) |
(opcode == OP_LUI ) |
(opcode == OP_BRANCH) |
(opcode == OP_JALR ) |
(opcode == OP_SYSTEM ) |
(opcode == OP_JAL ))) begin
$display("Unknown opcode %b at %0t", opcode, $time);
end // if ((opcode != OP_LOAD) |...
end // if (i_wb_en)
`endif
endmodule