mirror of
https://github.com/openhwgroup/cve2.git
synced 2025-04-23 05:27:30 -04:00
New version of divider, variable latency and thus faster on average
This commit is contained in:
parent
4401708fdb
commit
41dc5f3aa0
5 changed files with 344 additions and 253 deletions
70
alu.sv
70
alu.sv
|
@ -72,7 +72,13 @@ module riscv_alu
|
|||
end
|
||||
endgenerate
|
||||
|
||||
logic [31:0] operand_b_neg;
|
||||
|
||||
assign operand_b_neg = ~operand_b_i;
|
||||
|
||||
|
||||
logic [5:0] div_shift;
|
||||
logic div_valid;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// ____ _ _ _ _ _ _ _ _ //
|
||||
|
@ -92,7 +98,7 @@ module riscv_alu
|
|||
assign adder_op_a = (operator_i == `ALU_ABS) ? operand_a_neg : operand_a_i;
|
||||
|
||||
// prepare operand b
|
||||
assign adder_op_b = (operator_i == `ALU_SUB) ? ~operand_b_i : operand_b_i;
|
||||
assign adder_op_b = (operator_i == `ALU_SUB) ? operand_b_neg : operand_b_i;
|
||||
|
||||
// prepare carry
|
||||
always_comb
|
||||
|
@ -180,6 +186,8 @@ module riscv_alu
|
|||
logic [31:0] shift_right_result;
|
||||
logic [31:0] shift_left_result;
|
||||
|
||||
// shifter is also used for preparing operand for divison
|
||||
assign shift_amt = div_valid ? div_shift : operand_b_i;
|
||||
|
||||
// by reversing the bits of the input, we also have to reverse the order of shift amounts
|
||||
always_comb
|
||||
|
@ -208,7 +216,9 @@ module riscv_alu
|
|||
|
||||
// `ALU_FL1 and `ALU_CBL are used for the bit counting ops later
|
||||
assign shift_left = (operator_i == `ALU_SLL) || (operator_i == `ALU_BINS) ||
|
||||
(operator_i == `ALU_FL1) || (operator_i == `ALU_CLB);
|
||||
(operator_i == `ALU_FL1) || (operator_i == `ALU_CLB) ||
|
||||
(operator_i == `ALU_DIV) || (operator_i == `ALU_DIVU) ||
|
||||
(operator_i == `ALU_REM) || (operator_i == `ALU_REMU);
|
||||
|
||||
// choose the bit reversed or the normal input for shift operand a
|
||||
assign shift_op_a = (shift_left == 1'b1) ? operand_a_rev : operand_a_i;
|
||||
|
@ -643,7 +653,8 @@ module riscv_alu
|
|||
|
||||
logic [31:0] ff_input; // either op_a_i or its bit reversed version
|
||||
logic [5:0] cnt_result; // population count
|
||||
logic [5:0] clb_result; // count leading bits
|
||||
logic [5:0] clb_result; // count leading bits
|
||||
logic [5:0] clbu_result; // count leading bits
|
||||
logic [5:0] ff1_result; // holds the index of the first '1'
|
||||
logic ff_no_one; // if no ones are found
|
||||
logic [5:0] fl1_result; // holds the index of the last '1'
|
||||
|
@ -661,7 +672,13 @@ module riscv_alu
|
|||
|
||||
case (operator_i)
|
||||
`ALU_FF1: ff_input = operand_a_i;
|
||||
|
||||
`ALU_DIVU,
|
||||
`ALU_REMU,
|
||||
`ALU_FL1: ff_input = operand_a_rev;
|
||||
|
||||
`ALU_DIV,
|
||||
`ALU_REM,
|
||||
`ALU_CLB: begin
|
||||
if (operand_a_i[31])
|
||||
ff_input = operand_a_neg_rev;
|
||||
|
@ -680,8 +697,9 @@ module riscv_alu
|
|||
|
||||
// special case if ff1_res is 0 (no 1 found), then we keep the 0
|
||||
// this is done in the result mux
|
||||
assign fl1_result = 6'd33 - ff1_result;
|
||||
assign clb_result = ff1_result - 6'd2;
|
||||
assign fl1_result = 6'd33 - ff1_result;
|
||||
assign clb_result = ff1_result - 6'd2;
|
||||
assign clbu_result = ff1_result - 6'd1; // unsigned case, count one less
|
||||
|
||||
always_comb
|
||||
begin
|
||||
|
@ -742,34 +760,45 @@ module riscv_alu
|
|||
|
||||
logic [31:0] result_div;
|
||||
|
||||
logic div_valid;
|
||||
logic div_ready;
|
||||
logic div_signed;
|
||||
logic div_rem_quot;
|
||||
logic div_op_a_signed;
|
||||
logic div_op_b_signed;
|
||||
logic [5:0] div_shift_int;
|
||||
|
||||
assign div_signed = operator_i[0];
|
||||
|
||||
assign div_op_a_signed = operand_a_i[31] & div_signed;
|
||||
assign div_op_b_signed = operand_b_i[31] & div_signed;
|
||||
|
||||
assign div_shift_int = (ff_no_one) ? 6'd31 : clb_result;
|
||||
assign div_shift = div_shift_int + (div_op_a_signed ? 6'd0 : 6'd1);
|
||||
|
||||
assign div_valid = (operator_i == `ALU_DIV) || (operator_i == `ALU_DIVU) ||
|
||||
(operator_i == `ALU_REM) || (operator_i == `ALU_REMU);
|
||||
|
||||
assign div_rem_quot = operator_i[1];
|
||||
|
||||
assign div_signed = operator_i[0];
|
||||
|
||||
// inputs A and B are swapped
|
||||
riscv_alu_div div_i
|
||||
(
|
||||
.clk ( clk ),
|
||||
.rst_n ( rst_n ),
|
||||
.Clk_CI ( clk ),
|
||||
.Rst_RBI ( rst_n ),
|
||||
|
||||
.a_i ( operand_a_i ),
|
||||
.b_i ( operand_b_i ),
|
||||
.signed_i ( div_signed ),
|
||||
.rem_quot_i ( div_rem_quot ),
|
||||
// input IF
|
||||
.OpA_DI ( operand_b_i ),
|
||||
.OpB_DI ( shift_left_result ),
|
||||
.OpBShift_DI ( div_shift ),
|
||||
.OpBIsZero_SI ( (cnt_result == 0) ),
|
||||
|
||||
.result_o ( result_div ),
|
||||
.OpBSign_SI ( div_op_a_signed ),
|
||||
.OpCode_SI ( operator_i[1:0] ),
|
||||
|
||||
.div_valid_i ( div_valid ),
|
||||
.div_ready_o ( div_ready ),
|
||||
.ex_ready_i ( ex_ready_i )
|
||||
.Res_DO ( result_div ),
|
||||
|
||||
// Hand-Shake
|
||||
.InVld_SI ( div_valid ),
|
||||
.OutRdy_SI ( ex_ready_i ),
|
||||
.OutVld_SO ( div_ready )
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
|
@ -783,7 +812,6 @@ module riscv_alu
|
|||
|
||||
always_comb
|
||||
begin
|
||||
shift_amt = operand_b_i;
|
||||
result_o = 'x;
|
||||
|
||||
unique case (operator_i)
|
||||
|
|
329
alu_div.sv
329
alu_div.sv
|
@ -1,197 +1,214 @@
|
|||
// Copyright 2016 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the “License”); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// this module produces both the absolute (positive) value and the negative
|
||||
// value for any input. Both signed and unsigned numbers are supported
|
||||
module riscv_alu_abs_neg
|
||||
(
|
||||
input logic [31:0] in_i, // can be either signed or unsigned
|
||||
input logic signed_i,
|
||||
|
||||
output logic [32:0] abs_o, // needs to be 33 bits wide to allow for -(-2**31)
|
||||
output logic [32:0] neg_o // needs to be 33 bits wide to allow for -(2**32-1)
|
||||
);
|
||||
|
||||
logic [32:0] in_neg;
|
||||
|
||||
assign in_neg = -{(signed_i & in_i[31]), in_i};
|
||||
|
||||
assign abs_o = (signed_i & in_i[31]) ? in_neg : {1'b0, in_i};
|
||||
assign neg_o = (signed_i & in_i[31]) ? {1'b1, in_i} : in_neg;
|
||||
|
||||
endmodule
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// File : Simple Serial Divider
|
||||
// Ver : 1.0
|
||||
// Date : 15.03.2016
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Description: this is a simple serial divider for signed integers (int32).
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Authors : Michael Schaffner (schaffner@iis.ee.ethz.ch)
|
||||
// Andreas Traber (traber@iis.ee.ethz.ch)
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module riscv_alu_div
|
||||
#(
|
||||
parameter C_WIDTH = 32,
|
||||
parameter C_LOG_WIDTH = 6
|
||||
)
|
||||
(
|
||||
input logic clk,
|
||||
input logic rst_n,
|
||||
|
||||
input logic [31:0] a_i, // can be either signed or unsigned
|
||||
input logic [31:0] b_i, // can be either signed or unsigned
|
||||
input logic signed_i,
|
||||
input logic rem_quot_i, // 1 for rem, 0 for div
|
||||
|
||||
output logic [31:0] result_o,
|
||||
|
||||
// handshake
|
||||
input logic div_valid_i, // valid data available for division
|
||||
output logic div_ready_o, // set when done or idle
|
||||
|
||||
input logic ex_ready_i // if we have to wait for next stage
|
||||
);
|
||||
|
||||
enum logic [1:0] { IDLE, DIV, DIV_DONE } CS, NS;
|
||||
|
||||
logic [31:0] quotient_q, quotient_n;
|
||||
logic [63:0] remainder_q, remainder_n, remainder_int;
|
||||
|
||||
logic [31:0] remainder_out;
|
||||
logic [31:0] quotient_out;
|
||||
logic [31:0] result_int;
|
||||
|
||||
logic [32:0] a_abs;
|
||||
logic [32:0] a_neg;
|
||||
|
||||
logic [32:0] b_abs;
|
||||
|
||||
logic [32:0] sub_val;
|
||||
|
||||
logic a_is_neg;
|
||||
logic b_is_neg;
|
||||
logic result_negate;
|
||||
logic quot_negate;
|
||||
logic rem_negate;
|
||||
logic geq_b;
|
||||
logic load_r;
|
||||
logic is_active;
|
||||
logic [4:0] counter_q, counter_n;
|
||||
|
||||
riscv_alu_abs_neg b_abs_neg_i
|
||||
(
|
||||
.in_i ( b_i ),
|
||||
.signed_i ( signed_i ),
|
||||
|
||||
.abs_o ( b_abs )
|
||||
input logic Clk_CI,
|
||||
input logic Rst_RBI,
|
||||
// input IF
|
||||
input logic [C_WIDTH-1:0] OpA_DI,
|
||||
input logic [C_WIDTH-1:0] OpB_DI,
|
||||
input logic [C_LOG_WIDTH-1:0] OpBShift_DI,
|
||||
input logic OpBIsZero_SI,
|
||||
//
|
||||
input logic OpBSign_SI, // gate this to 0 in case of unsigned ops
|
||||
input logic [1:0] OpCode_SI, // 0: udiv, 2: urem, 1: div, 3: rem
|
||||
// handshake
|
||||
input logic InVld_SI,
|
||||
// output IF
|
||||
input logic OutRdy_SI,
|
||||
output logic OutVld_SO,
|
||||
output logic [C_WIDTH-1:0] Res_DO
|
||||
);
|
||||
|
||||
riscv_alu_abs_neg a_abs_neg_i
|
||||
(
|
||||
.in_i ( a_i ),
|
||||
.signed_i ( signed_i ),
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// signal declarations
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
.abs_o ( a_abs )
|
||||
);
|
||||
logic [C_WIDTH-1:0] ResReg_DP, ResReg_DN;
|
||||
logic [C_WIDTH-1:0] AReg_DP, AReg_DN;
|
||||
logic [C_WIDTH-1:0] BReg_DP, BReg_DN;
|
||||
|
||||
logic RemSel_SN, RemSel_SP;
|
||||
logic CompInv_SN, CompInv_SP;
|
||||
logic ResInv_SN, ResInv_SP;
|
||||
|
||||
logic [C_WIDTH-1:0] AddMux_D;
|
||||
logic [C_WIDTH-1:0] AddOut_D;
|
||||
logic [C_WIDTH-1:0] AddTmp_D;
|
||||
logic [C_WIDTH-1:0] BMux_D;
|
||||
logic [C_WIDTH-1:0] OutMux_D;
|
||||
|
||||
logic [C_LOG_WIDTH-1:0] Cnt_DP, Cnt_DN;
|
||||
logic CntZero_S;
|
||||
|
||||
logic ARegEn_S, BRegEn_S, ResRegEn_S, ABComp_S, PmSel_S, LoadEn_S;
|
||||
|
||||
enum logic [1:0] {IDLE, DIVIDE, FINISH} State_SN, State_SP;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// datapath
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
assign PmSel_S = LoadEn_S & ~(OpCode_SI[0] & (OpA_DI[$high(OpA_DI)] ^ OpBSign_SI));
|
||||
|
||||
// muxes
|
||||
assign AddMux_D = (LoadEn_S) ? OpA_DI : BReg_DP;
|
||||
|
||||
// attention: logical shift in case of negative operand B!
|
||||
assign BMux_D = (LoadEn_S) ? OpB_DI : {CompInv_SP, (BReg_DP[$high(BReg_DP):1])};
|
||||
|
||||
assign OutMux_D = (RemSel_SP) ? AReg_DP : {<<{ResReg_DP}};
|
||||
|
||||
// invert if necessary
|
||||
assign Res_DO = (ResInv_SP) ? -$signed(OutMux_D) : OutMux_D;
|
||||
|
||||
// main comparator
|
||||
assign ABComp_S = ((AReg_DP == BReg_DP) | ((AReg_DP > BReg_DP) ^ CompInv_SP)) & ((|AReg_DP) | OpBIsZero_SI);
|
||||
|
||||
// main adder
|
||||
assign AddTmp_D = (LoadEn_S) ? 0 : AReg_DP;
|
||||
assign AddOut_D = (PmSel_S) ? AddTmp_D + AddMux_D : AddTmp_D - $signed(AddMux_D);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// counter
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
assign Cnt_DN = (LoadEn_S) ? OpBShift_DI :
|
||||
(~CntZero_S) ? Cnt_DP - 1 : Cnt_DP;
|
||||
|
||||
assign CntZero_S = ~(|Cnt_DP);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// FSM
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
always_comb
|
||||
begin
|
||||
NS = CS;
|
||||
div_ready_o = 1'b1;
|
||||
load_r = 1'b0;
|
||||
is_active = 1'b0;
|
||||
counter_n = counter_q - 1;
|
||||
begin : p_fsm
|
||||
// default
|
||||
State_SN = State_SP;
|
||||
|
||||
case (CS)
|
||||
OutVld_SO = 1'b0;
|
||||
|
||||
LoadEn_S = 1'b0;
|
||||
|
||||
ARegEn_S = 1'b0;
|
||||
BRegEn_S = 1'b0;
|
||||
ResRegEn_S = 1'b0;
|
||||
|
||||
case (State_SP)
|
||||
/////////////////////////////////
|
||||
IDLE: begin
|
||||
div_ready_o = 1'b1;
|
||||
OutVld_SO = 1'b1;
|
||||
|
||||
if (div_valid_i) begin
|
||||
div_ready_o = 1'b0;
|
||||
NS = DIV;
|
||||
load_r = 1'b1;
|
||||
is_active = 1'b1;
|
||||
counter_n = 31;
|
||||
if(InVld_SI) begin
|
||||
OutVld_SO = 1'b0;
|
||||
ARegEn_S = 1'b1;
|
||||
BRegEn_S = 1'b1;
|
||||
LoadEn_S = 1'b1;
|
||||
State_SN = DIVIDE;
|
||||
end
|
||||
end
|
||||
/////////////////////////////////
|
||||
DIVIDE: begin
|
||||
|
||||
DIV: begin
|
||||
div_ready_o = 1'b0;
|
||||
is_active = 1'b1;
|
||||
ARegEn_S = ABComp_S;
|
||||
BRegEn_S = 1'b1;
|
||||
ResRegEn_S = 1'b1;
|
||||
|
||||
if (counter_q == 0) begin
|
||||
NS = DIV_DONE;
|
||||
// calculation finished
|
||||
// one more divide cycle (32nd divide cycle)
|
||||
if (CntZero_S) begin
|
||||
State_SN = FINISH;
|
||||
end
|
||||
end
|
||||
/////////////////////////////////
|
||||
FINISH: begin
|
||||
OutVld_SO = 1'b1;
|
||||
|
||||
// if the next stage was stalled when we finished
|
||||
DIV_DONE: begin
|
||||
div_ready_o = 1'b1;
|
||||
|
||||
if (ex_ready_i)
|
||||
NS = IDLE;
|
||||
if(OutRdy_SI) begin
|
||||
State_SN = IDLE;
|
||||
end
|
||||
end
|
||||
/////////////////////////////////
|
||||
default : /* default */ ;
|
||||
/////////////////////////////////
|
||||
endcase
|
||||
end
|
||||
|
||||
assign a_is_neg = a_i[31];
|
||||
assign b_is_neg = b_i[31];
|
||||
|
||||
assign quot_negate = ((a_is_neg ^ b_is_neg) && signed_i && (b_i != 0));
|
||||
assign rem_negate = a_is_neg && signed_i;
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// regs
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
assign geq_b = (remainder_q[63:31] >= b_abs);
|
||||
// get flags
|
||||
assign RemSel_SN = (LoadEn_S) ? OpCode_SI[1] : RemSel_SP;
|
||||
assign CompInv_SN = (LoadEn_S) ? OpBSign_SI : CompInv_SP;
|
||||
assign ResInv_SN = (LoadEn_S) ? (~OpBIsZero_SI | OpCode_SI[1]) & OpCode_SI[0] & (OpA_DI[$high(OpA_DI)] ^ OpBSign_SI) : ResInv_SP;
|
||||
|
||||
always_comb
|
||||
begin
|
||||
quotient_n = {quotient_q[30:0], 1'b0};
|
||||
sub_val = '0;
|
||||
assign AReg_DN = (ARegEn_S) ? AddOut_D : AReg_DP;
|
||||
assign BReg_DN = (BRegEn_S) ? BMux_D : BReg_DP;
|
||||
assign ResReg_DN = (LoadEn_S) ? '0 :
|
||||
(ResRegEn_S) ? {ABComp_S, ResReg_DP[$high(ResReg_DP):1]} : ResReg_DP;
|
||||
|
||||
if (geq_b) begin
|
||||
sub_val = b_abs;
|
||||
quotient_n = {quotient_q[30:0], 1'b1};
|
||||
end
|
||||
end
|
||||
|
||||
always_comb
|
||||
begin
|
||||
// add (or actually subtract) and shift left by one
|
||||
remainder_int[63:32] = remainder_q[63:31] - sub_val;
|
||||
remainder_int[31: 0] = {remainder_q[30:0], 1'b0};
|
||||
end
|
||||
|
||||
assign remainder_n = load_r ? {31'b0, a_abs} : remainder_int;
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// registers
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
always_ff @(posedge clk, negedge rst_n)
|
||||
begin
|
||||
if (~rst_n) begin
|
||||
quotient_q <= '0;
|
||||
remainder_q <= '0;
|
||||
counter_q <= 0;
|
||||
CS <= IDLE;
|
||||
always_ff @(posedge Clk_CI or negedge Rst_RBI) begin : p_regs
|
||||
if(~Rst_RBI) begin
|
||||
State_SP <= IDLE;
|
||||
AReg_DP <= '0;
|
||||
BReg_DP <= '0;
|
||||
ResReg_DP <= '0;
|
||||
Cnt_DP <= '0;
|
||||
RemSel_SP <= 1'b0;
|
||||
CompInv_SP <= 1'b0;
|
||||
ResInv_SP <= 1'b0;
|
||||
end else begin
|
||||
// only toggle when there is an active request
|
||||
if (is_active) begin
|
||||
quotient_q <= quotient_n;
|
||||
remainder_q <= remainder_n;
|
||||
counter_q <= counter_n;
|
||||
end
|
||||
CS <= NS;
|
||||
State_SP <= State_SN;
|
||||
AReg_DP <= AReg_DN;
|
||||
BReg_DP <= BReg_DN;
|
||||
ResReg_DP <= ResReg_DN;
|
||||
Cnt_DP <= Cnt_DN;
|
||||
RemSel_SP <= RemSel_SN;
|
||||
CompInv_SP <= CompInv_SN;
|
||||
ResInv_SP <= ResInv_SN;
|
||||
end
|
||||
end
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// assertions
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// output assignments
|
||||
//----------------------------------------------------------------------------
|
||||
`ifndef SYNTHESIS
|
||||
initial
|
||||
begin : p_assertions
|
||||
assert (C_LOG_WIDTH == $clog2(C_WIDTH+1)) else $error("C_LOG_WIDTH must be $clog2(C_WIDTH+1)");
|
||||
end
|
||||
`endif
|
||||
|
||||
assign quotient_out = quotient_q;
|
||||
assign remainder_out = remainder_q[63:32];
|
||||
assign result_int = rem_quot_i ? remainder_out : quotient_out;
|
||||
assign result_negate = rem_quot_i ? rem_negate : quot_negate;
|
||||
|
||||
|
||||
assign result_o = result_negate ? -result_int : result_int;
|
||||
|
||||
endmodule
|
||||
endmodule // serDiv
|
||||
|
|
116
decoder.sv
116
decoder.sv
|
@ -55,7 +55,8 @@ module riscv_decoder
|
|||
output logic [1:0] alu_op_c_mux_sel_o, // operand c selection: reg value or jump target
|
||||
output logic [1:0] alu_vec_mode_o, // selects between 32 bit, 16 bit and 8 bit vectorial modes
|
||||
output logic scalar_replication_o, // scalar replication enable
|
||||
output logic [3:0] immediate_mux_sel_o, // immediate selection for operand b
|
||||
output logic [0:0] imm_a_mux_sel_o, // immediate selection for operand a
|
||||
output logic [3:0] imm_b_mux_sel_o, // immediate selection for operand b
|
||||
output logic [1:0] regc_mux_o, // register c selection: S3, RD or 0
|
||||
|
||||
// MUL related control signals
|
||||
|
@ -133,7 +134,8 @@ module riscv_decoder
|
|||
alu_vec_mode_o = `VEC_MODE32;
|
||||
scalar_replication_o = 1'b0;
|
||||
regc_mux_o = `REGC_ZERO;
|
||||
immediate_mux_sel_o = `IMM_I;
|
||||
imm_a_mux_sel_o = `IMMA_ZERO;
|
||||
imm_b_mux_sel_o = `IMMB_I;
|
||||
|
||||
mult_en = 1'b0;
|
||||
mult_signed_mode_o = 2'b00;
|
||||
|
@ -191,7 +193,7 @@ module riscv_decoder
|
|||
// Calculate and store PC+4
|
||||
alu_op_a_mux_sel_o = `OP_A_CURRPC;
|
||||
alu_op_b_mux_sel_o = `OP_B_IMM;
|
||||
immediate_mux_sel_o = `IMM_PCINCR;
|
||||
imm_b_mux_sel_o = `IMMB_PCINCR;
|
||||
alu_operator_o = `ALU_ADD;
|
||||
regfile_alu_we = 1'b1;
|
||||
// Calculate jump target (= PC + UJ imm)
|
||||
|
@ -203,7 +205,7 @@ module riscv_decoder
|
|||
// Calculate and store PC+4
|
||||
alu_op_a_mux_sel_o = `OP_A_CURRPC;
|
||||
alu_op_b_mux_sel_o = `OP_B_IMM;
|
||||
immediate_mux_sel_o = `IMM_PCINCR;
|
||||
imm_b_mux_sel_o = `IMMB_PCINCR;
|
||||
alu_operator_o = `ALU_ADD;
|
||||
regfile_alu_we = 1'b1;
|
||||
// Calculate jump target (= RS1 + I imm)
|
||||
|
@ -268,7 +270,7 @@ module riscv_decoder
|
|||
|
||||
if (instr_rdata_i[14] == 1'b0) begin
|
||||
// offset from immediate
|
||||
immediate_mux_sel_o = `IMM_S;
|
||||
imm_b_mux_sel_o = `IMMB_S;
|
||||
alu_op_b_mux_sel_o = `OP_B_IMM;
|
||||
end else begin
|
||||
// offset from register
|
||||
|
@ -300,7 +302,7 @@ module riscv_decoder
|
|||
// offset from immediate
|
||||
alu_operator_o = `ALU_ADD;
|
||||
alu_op_b_mux_sel_o = `OP_B_IMM;
|
||||
immediate_mux_sel_o = `IMM_I;
|
||||
imm_b_mux_sel_o = `IMMB_I;
|
||||
|
||||
// post-increment setup
|
||||
if (instr_rdata_i[6:0] == `OPCODE_LOAD_POST) begin
|
||||
|
@ -368,9 +370,10 @@ module riscv_decoder
|
|||
//////////////////////////
|
||||
|
||||
`OPCODE_LUI: begin // Load Upper Immediate
|
||||
alu_op_a_mux_sel_o = `OP_A_ZERO;
|
||||
alu_op_a_mux_sel_o = `OP_A_IMM;
|
||||
alu_op_b_mux_sel_o = `OP_B_IMM;
|
||||
immediate_mux_sel_o = `IMM_U;
|
||||
imm_a_mux_sel_o = `IMMA_ZERO;
|
||||
imm_b_mux_sel_o = `IMMB_U;
|
||||
alu_operator_o = `ALU_ADD;
|
||||
regfile_alu_we = 1'b1;
|
||||
end
|
||||
|
@ -378,14 +381,14 @@ module riscv_decoder
|
|||
`OPCODE_AUIPC: begin // Add Upper Immediate to PC
|
||||
alu_op_a_mux_sel_o = `OP_A_CURRPC;
|
||||
alu_op_b_mux_sel_o = `OP_B_IMM;
|
||||
immediate_mux_sel_o = `IMM_U;
|
||||
imm_b_mux_sel_o = `IMMB_U;
|
||||
alu_operator_o = `ALU_ADD;
|
||||
regfile_alu_we = 1'b1;
|
||||
end
|
||||
|
||||
`OPCODE_OPIMM: begin // Register-Immediate ALU Operations
|
||||
alu_op_b_mux_sel_o = `OP_B_IMM;
|
||||
immediate_mux_sel_o = `IMM_I;
|
||||
imm_b_mux_sel_o = `IMMB_I;
|
||||
regfile_alu_we = 1'b1;
|
||||
rega_used_o = 1'b1;
|
||||
|
||||
|
@ -426,11 +429,11 @@ module riscv_decoder
|
|||
imm_bmask_needed_o = 1'b1;
|
||||
|
||||
unique case (instr_rdata_i[14:12])
|
||||
3'b000: begin alu_operator_o = `ALU_BEXT; immediate_mux_sel_o = `IMM_S2; end
|
||||
3'b001: begin alu_operator_o = `ALU_BEXTU; immediate_mux_sel_o = `IMM_S2; end
|
||||
3'b000: begin alu_operator_o = `ALU_BEXT; imm_b_mux_sel_o = `IMMB_S2; end
|
||||
3'b001: begin alu_operator_o = `ALU_BEXTU; imm_b_mux_sel_o = `IMMB_S2; end
|
||||
3'b010: begin
|
||||
alu_operator_o = `ALU_BINS;
|
||||
immediate_mux_sel_o = `IMM_S2;
|
||||
imm_b_mux_sel_o = `IMMB_S2;
|
||||
regc_used_o = 1'b1;
|
||||
regc_mux_o = `REGC_RD;
|
||||
end
|
||||
|
@ -469,15 +472,39 @@ module riscv_decoder
|
|||
mult_mac_en = 1'b1;
|
||||
end
|
||||
{6'b00_0001, 3'b100}: begin // div
|
||||
alu_operator_o = `ALU_DIV;
|
||||
alu_op_a_mux_sel_o = `OP_A_REGB_OR_FWD;
|
||||
alu_op_b_mux_sel_o = `OP_B_REGC_OR_FWD;
|
||||
regc_mux_o = `REGC_S1;
|
||||
regc_used_o = 1'b1;
|
||||
regb_used_o = 1'b1;
|
||||
rega_used_o = 1'b0;
|
||||
alu_operator_o = `ALU_DIV;
|
||||
end
|
||||
{6'b00_0001, 3'b101}: begin // divu
|
||||
alu_op_a_mux_sel_o = `OP_A_REGB_OR_FWD;
|
||||
alu_op_b_mux_sel_o = `OP_B_REGC_OR_FWD;
|
||||
regc_mux_o = `REGC_S1;
|
||||
regc_used_o = 1'b1;
|
||||
regb_used_o = 1'b1;
|
||||
rega_used_o = 1'b0;
|
||||
alu_operator_o = `ALU_DIVU;
|
||||
end
|
||||
{6'b00_0001, 3'b110}: begin // rem
|
||||
alu_op_a_mux_sel_o = `OP_A_REGB_OR_FWD;
|
||||
alu_op_b_mux_sel_o = `OP_B_REGC_OR_FWD;
|
||||
regc_mux_o = `REGC_S1;
|
||||
regc_used_o = 1'b1;
|
||||
regb_used_o = 1'b1;
|
||||
rega_used_o = 1'b0;
|
||||
alu_operator_o = `ALU_REM;
|
||||
end
|
||||
{6'b00_0001, 3'b111}: begin // remu
|
||||
alu_op_a_mux_sel_o = `OP_A_REGB_OR_FWD;
|
||||
alu_op_b_mux_sel_o = `OP_B_REGC_OR_FWD;
|
||||
regc_mux_o = `REGC_S1;
|
||||
regc_used_o = 1'b1;
|
||||
regb_used_o = 1'b1;
|
||||
rega_used_o = 1'b0;
|
||||
alu_operator_o = `ALU_REMU;
|
||||
end
|
||||
|
||||
|
@ -547,7 +574,7 @@ module riscv_decoder
|
|||
`OPCODE_VECOP: begin
|
||||
regfile_alu_we = 1'b1;
|
||||
rega_used_o = 1'b1;
|
||||
immediate_mux_sel_o = `IMM_VS;
|
||||
imm_b_mux_sel_o = `IMMB_VS;
|
||||
|
||||
// vector size
|
||||
if (instr_rdata_i[12])
|
||||
|
@ -573,21 +600,21 @@ module riscv_decoder
|
|||
|
||||
// now decode the instruction
|
||||
unique case (instr_rdata_i[31:26])
|
||||
6'b00000_0: begin alu_operator_o = `ALU_ADD; immediate_mux_sel_o = `IMM_VS; end // pv.add
|
||||
6'b00001_0: begin alu_operator_o = `ALU_SUB; immediate_mux_sel_o = `IMM_VS; end // pv.sub
|
||||
6'b00010_0: begin alu_operator_o = `ALU_AVG; immediate_mux_sel_o = `IMM_VS; end // pv.avg
|
||||
6'b00011_0: begin alu_operator_o = `ALU_AVGU; immediate_mux_sel_o = `IMM_VU; end // pv.avgu
|
||||
6'b00100_0: begin alu_operator_o = `ALU_MIN; immediate_mux_sel_o = `IMM_VS; end // pv.min
|
||||
6'b00101_0: begin alu_operator_o = `ALU_MINU; immediate_mux_sel_o = `IMM_VU; end // pv.minu
|
||||
6'b00110_0: begin alu_operator_o = `ALU_MAX; immediate_mux_sel_o = `IMM_VS; end // pv.max
|
||||
6'b00111_0: begin alu_operator_o = `ALU_MAXU; immediate_mux_sel_o = `IMM_VU; end // pv.maxu
|
||||
6'b01000_0: begin alu_operator_o = `ALU_SRL; immediate_mux_sel_o = `IMM_VS; end // pv.srl
|
||||
6'b01001_0: begin alu_operator_o = `ALU_SRA; immediate_mux_sel_o = `IMM_VS; end // pv.sra
|
||||
6'b01010_0: begin alu_operator_o = `ALU_SLL; immediate_mux_sel_o = `IMM_VS; end // pv.sll
|
||||
6'b01011_0: begin alu_operator_o = `ALU_OR; immediate_mux_sel_o = `IMM_VS; end // pv.or
|
||||
6'b01100_0: begin alu_operator_o = `ALU_XOR; immediate_mux_sel_o = `IMM_VS; end // pv.xor
|
||||
6'b01101_0: begin alu_operator_o = `ALU_AND; immediate_mux_sel_o = `IMM_VS; end // pv.and
|
||||
6'b01110_0: begin alu_operator_o = `ALU_ABS; immediate_mux_sel_o = `IMM_VS; end // pv.abs
|
||||
6'b00000_0: begin alu_operator_o = `ALU_ADD; imm_b_mux_sel_o = `IMMB_VS; end // pv.add
|
||||
6'b00001_0: begin alu_operator_o = `ALU_SUB; imm_b_mux_sel_o = `IMMB_VS; end // pv.sub
|
||||
6'b00010_0: begin alu_operator_o = `ALU_AVG; imm_b_mux_sel_o = `IMMB_VS; end // pv.avg
|
||||
6'b00011_0: begin alu_operator_o = `ALU_AVGU; imm_b_mux_sel_o = `IMMB_VU; end // pv.avgu
|
||||
6'b00100_0: begin alu_operator_o = `ALU_MIN; imm_b_mux_sel_o = `IMMB_VS; end // pv.min
|
||||
6'b00101_0: begin alu_operator_o = `ALU_MINU; imm_b_mux_sel_o = `IMMB_VU; end // pv.minu
|
||||
6'b00110_0: begin alu_operator_o = `ALU_MAX; imm_b_mux_sel_o = `IMMB_VS; end // pv.max
|
||||
6'b00111_0: begin alu_operator_o = `ALU_MAXU; imm_b_mux_sel_o = `IMMB_VU; end // pv.maxu
|
||||
6'b01000_0: begin alu_operator_o = `ALU_SRL; imm_b_mux_sel_o = `IMMB_VS; end // pv.srl
|
||||
6'b01001_0: begin alu_operator_o = `ALU_SRA; imm_b_mux_sel_o = `IMMB_VS; end // pv.sra
|
||||
6'b01010_0: begin alu_operator_o = `ALU_SLL; imm_b_mux_sel_o = `IMMB_VS; end // pv.sll
|
||||
6'b01011_0: begin alu_operator_o = `ALU_OR; imm_b_mux_sel_o = `IMMB_VS; end // pv.or
|
||||
6'b01100_0: begin alu_operator_o = `ALU_XOR; imm_b_mux_sel_o = `IMMB_VS; end // pv.xor
|
||||
6'b01101_0: begin alu_operator_o = `ALU_AND; imm_b_mux_sel_o = `IMMB_VS; end // pv.and
|
||||
6'b01110_0: begin alu_operator_o = `ALU_ABS; imm_b_mux_sel_o = `IMMB_VS; end // pv.abs
|
||||
|
||||
6'b01111_0: begin // pv.extract
|
||||
if (instr_rdata_i[12])
|
||||
|
@ -613,7 +640,7 @@ module riscv_decoder
|
|||
// shuffle/pack
|
||||
6'b11000_0: begin // pv.shuffle
|
||||
alu_operator_o = `ALU_SHUF;
|
||||
immediate_mux_sel_o = `IMM_SHUF;
|
||||
imm_b_mux_sel_o = `IMMB_SHUF;
|
||||
regb_used_o = 1'b1;
|
||||
scalar_replication_o = 1'b0;
|
||||
end
|
||||
|
@ -637,16 +664,16 @@ module riscv_decoder
|
|||
end
|
||||
|
||||
// comparisons, always have bit 26 set
|
||||
6'b00000_1: begin alu_operator_o = `ALU_EQ; immediate_mux_sel_o = `IMM_VS; end // pv.cmpeq
|
||||
6'b00001_1: begin alu_operator_o = `ALU_NE; immediate_mux_sel_o = `IMM_VS; end // pv.cmpne
|
||||
6'b00010_1: begin alu_operator_o = `ALU_GTU; immediate_mux_sel_o = `IMM_VS; end // pv.cmpgt
|
||||
6'b00011_1: begin alu_operator_o = `ALU_GES; immediate_mux_sel_o = `IMM_VS; end // pv.cmpge
|
||||
6'b00100_1: begin alu_operator_o = `ALU_LTU; immediate_mux_sel_o = `IMM_VS; end // pv.cmplt
|
||||
6'b00101_1: begin alu_operator_o = `ALU_LES; immediate_mux_sel_o = `IMM_VS; end // pv.cmple
|
||||
6'b00110_1: begin alu_operator_o = `ALU_GTU; immediate_mux_sel_o = `IMM_VU; end // pv.cmpgtu
|
||||
6'b00111_1: begin alu_operator_o = `ALU_GEU; immediate_mux_sel_o = `IMM_VU; end // pv.cmpgeu
|
||||
6'b01000_1: begin alu_operator_o = `ALU_LTU; immediate_mux_sel_o = `IMM_VU; end // pv.cmpltu
|
||||
6'b01001_1: begin alu_operator_o = `ALU_LEU; immediate_mux_sel_o = `IMM_VU; end // pv.cmpleu
|
||||
6'b00000_1: begin alu_operator_o = `ALU_EQ; imm_b_mux_sel_o = `IMMB_VS; end // pv.cmpeq
|
||||
6'b00001_1: begin alu_operator_o = `ALU_NE; imm_b_mux_sel_o = `IMMB_VS; end // pv.cmpne
|
||||
6'b00010_1: begin alu_operator_o = `ALU_GTU; imm_b_mux_sel_o = `IMMB_VS; end // pv.cmpgt
|
||||
6'b00011_1: begin alu_operator_o = `ALU_GES; imm_b_mux_sel_o = `IMMB_VS; end // pv.cmpge
|
||||
6'b00100_1: begin alu_operator_o = `ALU_LTU; imm_b_mux_sel_o = `IMMB_VS; end // pv.cmplt
|
||||
6'b00101_1: begin alu_operator_o = `ALU_LES; imm_b_mux_sel_o = `IMMB_VS; end // pv.cmple
|
||||
6'b00110_1: begin alu_operator_o = `ALU_GTU; imm_b_mux_sel_o = `IMMB_VU; end // pv.cmpgtu
|
||||
6'b00111_1: begin alu_operator_o = `ALU_GEU; imm_b_mux_sel_o = `IMMB_VU; end // pv.cmpgeu
|
||||
6'b01000_1: begin alu_operator_o = `ALU_LTU; imm_b_mux_sel_o = `IMMB_VU; end // pv.cmpltu
|
||||
6'b01001_1: begin alu_operator_o = `ALU_LEU; imm_b_mux_sel_o = `IMMB_VU; end // pv.cmpleu
|
||||
|
||||
default: illegal_insn_o = 1'b1;
|
||||
endcase
|
||||
|
@ -702,11 +729,12 @@ module riscv_decoder
|
|||
csr_access_o = 1'b1;
|
||||
regfile_alu_we = 1'b1;
|
||||
alu_op_b_mux_sel_o = `OP_B_IMM;
|
||||
immediate_mux_sel_o = `IMM_I; // CSR address is encoded in I imm
|
||||
imm_a_mux_sel_o = `IMMA_Z;
|
||||
imm_b_mux_sel_o = `IMMB_I; // CSR address is encoded in I imm
|
||||
|
||||
if (instr_rdata_i[14] == 1'b1) begin
|
||||
// rs1 field is used as immediate
|
||||
alu_op_a_mux_sel_o = `OP_A_ZIMM;
|
||||
alu_op_a_mux_sel_o = `OP_A_IMM;
|
||||
end else begin
|
||||
rega_used_o = 1'b1;
|
||||
alu_op_a_mux_sel_o = `OP_A_REGA_OR_FWD;
|
||||
|
@ -802,7 +830,7 @@ module riscv_decoder
|
|||
// correct operands are sent to the AGU
|
||||
alu_op_a_mux_sel_o = `OP_A_REGA_OR_FWD;
|
||||
alu_op_b_mux_sel_o = `OP_B_IMM;
|
||||
immediate_mux_sel_o = `IMM_PCINCR;
|
||||
imm_b_mux_sel_o = `IMMB_PCINCR;
|
||||
|
||||
// if prepost increments are used, we do not write back the
|
||||
// second address since the first calculated address was
|
||||
|
|
51
id_stage.sv
51
id_stage.sv
|
@ -222,7 +222,8 @@ module riscv_id_stage
|
|||
logic [31:0] imm_vu_type;
|
||||
logic [31:0] imm_shuffle_type;
|
||||
|
||||
logic [31:0] immediate_b; // contains the immediate for operand b
|
||||
logic [31:0] imm_a; // contains the immediate for operand b
|
||||
logic [31:0] imm_b; // contains the immediate for operand b
|
||||
|
||||
logic [31:0] jump_target; // calculated jump target (-> EX -> IF)
|
||||
|
||||
|
@ -253,7 +254,8 @@ module riscv_id_stage
|
|||
logic [1:0] alu_op_c_mux_sel;
|
||||
logic [1:0] regc_mux;
|
||||
|
||||
logic [3:0] immediate_mux_sel;
|
||||
logic [0:0] imm_a_mux_sel;
|
||||
logic [3:0] imm_b_mux_sel;
|
||||
logic [1:0] jump_target_mux_sel;
|
||||
|
||||
// Multiplier Control
|
||||
|
@ -363,6 +365,7 @@ module riscv_id_stage
|
|||
`REGC_ZERO: regfile_addr_rc_id = '0;
|
||||
`REGC_RD: regfile_addr_rc_id = instr[`REG_D];
|
||||
`REGC_S3: regfile_addr_rc_id = instr[`REG_S3];
|
||||
`REGC_S1: regfile_addr_rc_id = instr[`REG_S1];
|
||||
default: regfile_addr_rc_id = '0;
|
||||
endcase
|
||||
end
|
||||
|
@ -483,13 +486,22 @@ module riscv_id_stage
|
|||
begin : alu_operand_a_mux
|
||||
case (alu_op_a_mux_sel)
|
||||
`OP_A_REGA_OR_FWD: alu_operand_a = operand_a_fw_id;
|
||||
`OP_A_REGB_OR_FWD: alu_operand_a = operand_b_fw_id;
|
||||
`OP_A_CURRPC: alu_operand_a = pc_id_i;
|
||||
`OP_A_ZIMM: alu_operand_a = imm_z_type;
|
||||
`OP_A_ZERO: alu_operand_a = 32'b0;
|
||||
`OP_A_IMM: alu_operand_a = imm_a;
|
||||
default: alu_operand_a = operand_a_fw_id;
|
||||
endcase; // case (alu_op_a_mux_sel)
|
||||
end
|
||||
|
||||
always_comb
|
||||
begin : immediate_a_mux
|
||||
unique case (imm_a_mux_sel)
|
||||
`IMMA_Z: imm_a = imm_z_type;
|
||||
`IMMA_ZERO: imm_a = '0;
|
||||
default: imm_a = '0;
|
||||
endcase
|
||||
end
|
||||
|
||||
// Operand a forwarding mux
|
||||
always_comb
|
||||
begin : operand_a_fw_mux
|
||||
|
@ -514,19 +526,19 @@ module riscv_id_stage
|
|||
// TODO: check if sign-extension stuff works well here, maybe able to save
|
||||
// some area here
|
||||
always_comb
|
||||
begin : immediate_mux
|
||||
unique case (immediate_mux_sel)
|
||||
`IMM_I: immediate_b = imm_i_type;
|
||||
`IMM_S: immediate_b = imm_s_type;
|
||||
`IMM_U: immediate_b = imm_u_type;
|
||||
`IMM_PCINCR: immediate_b = (is_compressed_i && (~data_misaligned_i)) ? 32'h2 : 32'h4;
|
||||
`IMM_S2: immediate_b = imm_s2_type;
|
||||
`IMM_S3: immediate_b = imm_s3_type;
|
||||
`IMM_VS: immediate_b = imm_vs_type;
|
||||
`IMM_VU: immediate_b = imm_vu_type;
|
||||
`IMM_SHUF: immediate_b = imm_shuffle_type;
|
||||
default: immediate_b = imm_i_type;
|
||||
endcase; // case (immediate_mux_sel)
|
||||
begin : immediate_b_mux
|
||||
unique case (imm_b_mux_sel)
|
||||
`IMMB_I: imm_b = imm_i_type;
|
||||
`IMMB_S: imm_b = imm_s_type;
|
||||
`IMMB_U: imm_b = imm_u_type;
|
||||
`IMMB_PCINCR: imm_b = (is_compressed_i && (~data_misaligned_i)) ? 32'h2 : 32'h4;
|
||||
`IMMB_S2: imm_b = imm_s2_type;
|
||||
`IMMB_S3: imm_b = imm_s3_type;
|
||||
`IMMB_VS: imm_b = imm_vs_type;
|
||||
`IMMB_VU: imm_b = imm_vu_type;
|
||||
`IMMB_SHUF: imm_b = imm_shuffle_type;
|
||||
default: imm_b = imm_i_type;
|
||||
endcase
|
||||
end
|
||||
|
||||
// ALU_Op_b Mux
|
||||
|
@ -535,7 +547,7 @@ module riscv_id_stage
|
|||
case (alu_op_b_mux_sel)
|
||||
`OP_B_REGB_OR_FWD: operand_b = operand_b_fw_id;
|
||||
`OP_B_REGC_OR_FWD: operand_b = operand_c_fw_id;
|
||||
`OP_B_IMM: operand_b = immediate_b;
|
||||
`OP_B_IMM: operand_b = imm_b;
|
||||
default: operand_b = operand_b_fw_id;
|
||||
endcase // case (alu_op_b_mux_sel)
|
||||
end
|
||||
|
@ -686,7 +698,8 @@ module riscv_id_stage
|
|||
.alu_op_c_mux_sel_o ( alu_op_c_mux_sel ),
|
||||
.alu_vec_mode_o ( alu_vec_mode ),
|
||||
.scalar_replication_o ( scalar_replication ),
|
||||
.immediate_mux_sel_o ( immediate_mux_sel ),
|
||||
.imm_a_mux_sel_o ( imm_a_mux_sel ),
|
||||
.imm_b_mux_sel_o ( imm_b_mux_sel ),
|
||||
.regc_mux_o ( regc_mux ),
|
||||
|
||||
// MUL signals
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
// no traces for synthesis, they are not synthesizable
|
||||
`ifndef SYNTHESIS
|
||||
`define TRACE_EXECUTION
|
||||
`define SIMCHECKER
|
||||
//`define SIMCHECKER
|
||||
`endif
|
||||
|
||||
|
||||
|
@ -76,6 +76,7 @@
|
|||
`define REGC_ZERO 2'b00
|
||||
`define REGC_RD 2'b01
|
||||
`define REGC_S3 2'b10
|
||||
`define REGC_S1 2'b11
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -218,24 +219,28 @@
|
|||
// operand a selection
|
||||
`define OP_A_REGA_OR_FWD 2'b00
|
||||
`define OP_A_CURRPC 2'b01
|
||||
`define OP_A_ZIMM 2'b10
|
||||
`define OP_A_ZERO 2'b11
|
||||
`define OP_A_IMM 2'b10
|
||||
`define OP_A_REGB_OR_FWD 2'b11
|
||||
|
||||
// immediate b selection
|
||||
`define IMMA_Z 1'b0
|
||||
`define IMMA_ZERO 1'b1
|
||||
|
||||
// operand b selection
|
||||
`define OP_B_REGB_OR_FWD 2'b00
|
||||
`define OP_B_REGC_OR_FWD 2'b01
|
||||
`define OP_B_IMM 2'b10
|
||||
|
||||
// operand b immediate selection
|
||||
`define IMM_I 4'b0000
|
||||
`define IMM_S 4'b0001
|
||||
`define IMM_U 4'b0010
|
||||
`define IMM_PCINCR 4'b0011
|
||||
`define IMM_S2 4'b0100
|
||||
`define IMM_S3 4'b0101
|
||||
`define IMM_VS 4'b0110
|
||||
`define IMM_VU 4'b0111
|
||||
`define IMM_SHUF 4'b1000
|
||||
// immediate b selection
|
||||
`define IMMB_I 4'b0000
|
||||
`define IMMB_S 4'b0001
|
||||
`define IMMB_U 4'b0010
|
||||
`define IMMB_PCINCR 4'b0011
|
||||
`define IMMB_S2 4'b0100
|
||||
`define IMMB_S3 4'b0101
|
||||
`define IMMB_VS 4'b0110
|
||||
`define IMMB_VU 4'b0111
|
||||
`define IMMB_SHUF 4'b1000
|
||||
|
||||
// operand c selection
|
||||
`define OP_C_REGC_OR_FWD 2'b00
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue