Change how constants are plumbed through the hierarchy. Some small cleanups of variable declaration order etc
This commit is contained in:
parent
6dad4e20bb
commit
5de4f01aae
2
License
2
License
|
@ -1,7 +1,7 @@
|
||||||
DO WHAT THE FUCK YOU WANT TO AND DON'T BLAME US PUBLIC LICENSE
|
DO WHAT THE FUCK YOU WANT TO AND DON'T BLAME US PUBLIC LICENSE
|
||||||
Version 3, April 2008
|
Version 3, April 2008
|
||||||
|
|
||||||
Copyright (C) 2020 Luke Wren
|
Copyright (C) 2021 Luke Wren
|
||||||
|
|
||||||
Everyone is permitted to copy and distribute verbatim or modified
|
Everyone is permitted to copy and distribute verbatim or modified
|
||||||
copies of this license document and accompanying software, and
|
copies of this license document and accompanying software, and
|
||||||
|
|
|
@ -30,20 +30,21 @@
|
||||||
module hazard5_muldiv_seq #(
|
module hazard5_muldiv_seq #(
|
||||||
parameter XLEN = 32,
|
parameter XLEN = 32,
|
||||||
parameter UNROLL = 1,
|
parameter UNROLL = 1,
|
||||||
parameter W_CTR = $clog2(XLEN + 1) // do not modify
|
parameter W_CTR = $clog2(XLEN + 1), // do not modify
|
||||||
|
`include "hazard5_width_const.vh"
|
||||||
) (
|
) (
|
||||||
input wire clk,
|
input wire clk,
|
||||||
input wire rst_n,
|
input wire rst_n,
|
||||||
input wire [2:0] op,
|
input wire [W_MULOP-1:0] op,
|
||||||
input wire op_vld,
|
input wire op_vld,
|
||||||
output wire op_rdy,
|
output wire op_rdy,
|
||||||
input wire op_kill,
|
input wire op_kill,
|
||||||
input wire [XLEN-1:0] op_a,
|
input wire [XLEN-1:0] op_a,
|
||||||
input wire [XLEN-1:0] op_b,
|
input wire [XLEN-1:0] op_b,
|
||||||
|
|
||||||
output wire [XLEN-1:0] result_h, // mulh* or rem*
|
output wire [XLEN-1:0] result_h, // mulh* or rem*
|
||||||
output wire [XLEN-1:0] result_l, // mul or div*
|
output wire [XLEN-1:0] result_l, // mul or div*
|
||||||
output wire result_vld
|
output wire result_vld
|
||||||
);
|
);
|
||||||
|
|
||||||
`include "hazard5_ops.vh"
|
`include "hazard5_ops.vh"
|
||||||
|
|
|
@ -1,72 +0,0 @@
|
||||||
/**********************************************************************
|
|
||||||
* DO WHAT THE FUCK YOU WANT TO AND DON'T BLAME US PUBLIC LICENSE *
|
|
||||||
* Version 3, April 2008 *
|
|
||||||
* *
|
|
||||||
* Copyright (C) 2018 Luke Wren *
|
|
||||||
* *
|
|
||||||
* Everyone is permitted to copy and distribute verbatim or modified *
|
|
||||||
* copies of this license document and accompanying software, and *
|
|
||||||
* changing either is allowed. *
|
|
||||||
* *
|
|
||||||
* TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION *
|
|
||||||
* *
|
|
||||||
* 0. You just DO WHAT THE FUCK YOU WANT TO. *
|
|
||||||
* 1. We're NOT RESPONSIBLE WHEN IT DOESN'T FUCKING WORK. *
|
|
||||||
* *
|
|
||||||
*********************************************************************/
|
|
||||||
|
|
||||||
module hazard5_shift_1bit_seq #(
|
|
||||||
parameter W_DATA = 32,
|
|
||||||
parameter W_SHAMT = 5
|
|
||||||
) (
|
|
||||||
input wire clk,
|
|
||||||
input wire rst_n,
|
|
||||||
|
|
||||||
input wire [W_DATA-1:0] din,
|
|
||||||
input wire din_vld, // can be asserted at any time, we always respond
|
|
||||||
input wire [W_SHAMT-1:0] shamt,
|
|
||||||
input wire right_nleft,
|
|
||||||
input wire arith,
|
|
||||||
output wire [W_DATA-1:0] dout,
|
|
||||||
output wire dout_vld,
|
|
||||||
);
|
|
||||||
|
|
||||||
reg [W_DATA-1:0] accum;
|
|
||||||
reg [W_DATA-1:0] accum_next;
|
|
||||||
reg [W_SHAMT-1:0] shamt_remaining;
|
|
||||||
reg flipped;
|
|
||||||
|
|
||||||
// Handle actual shifting
|
|
||||||
|
|
||||||
wire sext = arith && accum[W_DATA - 1];
|
|
||||||
|
|
||||||
always @ (*) begin: shift_unit
|
|
||||||
accum_next = accum;
|
|
||||||
if (din_vld) begin
|
|
||||||
accum_next = din;
|
|
||||||
end else if (shamt_remaining) begin
|
|
||||||
if (right_nleft)
|
|
||||||
accum_next = {sext, accum[W_DATA-1:1]};
|
|
||||||
else
|
|
||||||
accum_next = {accum << 1};
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
// No reset on datapath
|
|
||||||
always @ (posedge clk)
|
|
||||||
accum <= accum_next;
|
|
||||||
|
|
||||||
always @ (posedge clk or negedge rst_n) begin
|
|
||||||
if (!rst_n) begin
|
|
||||||
shamt_remaining <= {W_SHAMT{1'b0}};
|
|
||||||
end else if (din_vld) begin
|
|
||||||
shamt_remaining <= shamt;
|
|
||||||
end else begin
|
|
||||||
shamt_remaining <= shamt_remaining - |shamt_remaining;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
assign dout_vld = shamt_remaining == 0;
|
|
||||||
assign dout = accum;
|
|
||||||
|
|
||||||
endmodule
|
|
|
@ -1,106 +0,0 @@
|
||||||
/**********************************************************************
|
|
||||||
* DO WHAT THE FUCK YOU WANT TO AND DON'T BLAME US PUBLIC LICENSE *
|
|
||||||
* Version 3, April 2008 *
|
|
||||||
* *
|
|
||||||
* Copyright (C) 2018 Luke Wren *
|
|
||||||
* *
|
|
||||||
* Everyone is permitted to copy and distribute verbatim or modified *
|
|
||||||
* copies of this license document and accompanying software, and *
|
|
||||||
* changing either is allowed. *
|
|
||||||
* *
|
|
||||||
* TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION *
|
|
||||||
* *
|
|
||||||
* 0. You just DO WHAT THE FUCK YOU WANT TO. *
|
|
||||||
* 1. We're NOT RESPONSIBLE WHEN IT DOESN'T FUCKING WORK. *
|
|
||||||
* *
|
|
||||||
*********************************************************************/
|
|
||||||
|
|
||||||
// Implement the three shifts using a single log-sequential shifter.
|
|
||||||
// On each clock, the shifter can left-shift by a power-of-two amount (arith or
|
|
||||||
// logical), OR it can reverse the accumulator.
|
|
||||||
//
|
|
||||||
// The accumulator is wired in reverse to the output. So the sequences are:
|
|
||||||
// - Right shift: flip, then shift. Output wiring flips again. Internal left-shifts
|
|
||||||
// are effectively right shifts.
|
|
||||||
// - Left shift: perform shift ops, then flip, so that reversed output cancels.
|
|
||||||
//
|
|
||||||
// An additional cycle is consumed to load the input into the accumulator; this
|
|
||||||
// simplifies muxing. In total, a shift consumes between 2 and 7 cycles on a
|
|
||||||
// 32-bit machine, depending on the bit weight of shamt.
|
|
||||||
|
|
||||||
module hazard5_shift_log_seq #(
|
|
||||||
parameter W_DATA = 32,
|
|
||||||
parameter W_SHAMT = 5
|
|
||||||
) (
|
|
||||||
input wire clk,
|
|
||||||
input wire rst_n,
|
|
||||||
|
|
||||||
input wire [W_DATA-1:0] din,
|
|
||||||
input wire din_vld, // can be asserted at any time, we always respond
|
|
||||||
input wire [W_SHAMT-1:0] shamt,
|
|
||||||
input wire right_nleft,
|
|
||||||
input wire arith,
|
|
||||||
output reg [W_DATA-1:0] dout,
|
|
||||||
output reg dout_vld,
|
|
||||||
);
|
|
||||||
|
|
||||||
reg [W_DATA-1:0] accum;
|
|
||||||
reg [W_DATA-1:0] accum_next;
|
|
||||||
reg [W_SHAMT-1:0] shamt_remaining;
|
|
||||||
reg flipped;
|
|
||||||
|
|
||||||
// Handle actual shifting
|
|
||||||
|
|
||||||
wire flip = !flipped && (right_nleft || ~|shamt_remaining);
|
|
||||||
wire sext = arith && accum[0]; // "Left arithmetic" shifting
|
|
||||||
|
|
||||||
always @ (*) begin: shift_unit
|
|
||||||
integer i;
|
|
||||||
accum_next = accum;
|
|
||||||
// The following is a priority mux tree (honest) which the synthesis tool should balance
|
|
||||||
if (din_vld) begin
|
|
||||||
accum_next = din;
|
|
||||||
end else if (flip) begin
|
|
||||||
for (i = 0; i < W_DATA; i = i + 1)
|
|
||||||
accum_next[i] = accum[W_DATA - 1 - i];
|
|
||||||
end else if (shamt_remaining) begin
|
|
||||||
// Smallest shift first
|
|
||||||
for (i = 0; i < W_SHAMT; i = i + 1) begin
|
|
||||||
if (shamt_remaining[i] && ~|(shamt_remaining & ~({W_SHAMT{1'b1}} << i))) begin
|
|
||||||
accum_next = (accum << (1 << i)) |
|
|
||||||
({W_DATA{sext}} & ~({W_DATA{1'b1}} << (1 << i)));
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
// No reset on datapath
|
|
||||||
always @ (posedge clk)
|
|
||||||
accum <= accum_next;
|
|
||||||
|
|
||||||
// State machine
|
|
||||||
|
|
||||||
always @ (posedge clk or negedge rst_n) begin
|
|
||||||
if (!rst_n) begin
|
|
||||||
shamt_remaining <= {W_SHAMT{1'b0}};
|
|
||||||
flipped <= 1'b0;
|
|
||||||
end else if (din_vld) begin
|
|
||||||
shamt_remaining <= shamt;
|
|
||||||
flipped <= 1'b0;
|
|
||||||
end else begin
|
|
||||||
if (flip)
|
|
||||||
flipped <= 1'b1;
|
|
||||||
else
|
|
||||||
shamt_remaining <= shamt_remaining & {shamt_remaining - 1'b1};
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
always @ (*) begin: connect_output
|
|
||||||
dout_vld = flipped && ~|shamt_remaining;
|
|
||||||
integer i;
|
|
||||||
for (i = 0; i < W_DATA; i = i + 1)
|
|
||||||
dout[i] = accum[W_DATA - 1 - i];
|
|
||||||
end
|
|
||||||
|
|
||||||
endmodule
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
// Pass-through of parameters defined in hazard5_config.vh, so that these can
|
||||||
|
// be set at instantiation rather than editing the config file, and will flow
|
||||||
|
// correctly down through the hierarchy.
|
||||||
|
|
||||||
|
.RESET_VECTOR (RESET_VECTOR),
|
||||||
|
.MTVEC_INIT (MTVEC_INIT),
|
||||||
|
.EXTENSION_C (EXTENSION_C),
|
||||||
|
.EXTENSION_M (EXTENSION_M),
|
||||||
|
.CSR_M_MANDATORY (CSR_M_MANDATORY),
|
||||||
|
.CSR_M_TRAP (CSR_M_TRAP),
|
||||||
|
.CSR_COUNTER (CSR_COUNTER),
|
||||||
|
.REDUCED_BYPASS (REDUCED_BYPASS),
|
||||||
|
.MULDIV_UNROLL (MULDIV_UNROLL),
|
||||||
|
.MUL_FAST (MUL_FAST),
|
||||||
|
.MTVEC_WMASK (MTVEC_WMASK),
|
||||||
|
.W_ADDR (W_ADDR),
|
||||||
|
.W_DATA (W_DATA)
|
|
@ -17,6 +17,8 @@
|
||||||
|
|
||||||
module hazard5_core #(
|
module hazard5_core #(
|
||||||
`include "hazard5_config.vh"
|
`include "hazard5_config.vh"
|
||||||
|
,
|
||||||
|
`include "hazard5_width_const.vh"
|
||||||
) (
|
) (
|
||||||
// Global signals
|
// Global signals
|
||||||
input wire clk,
|
input wire clk,
|
||||||
|
@ -70,11 +72,6 @@ module hazard5_core #(
|
||||||
//synthesis translate_on
|
//synthesis translate_on
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
localparam N_REGS = 32;
|
|
||||||
// should be localparam but ISIM can't cope
|
|
||||||
parameter W_REGADDR = $clog2(N_REGS);
|
|
||||||
localparam NOP_INSTR = 32'h13; // addi x0, x0, 0
|
|
||||||
|
|
||||||
wire flush_d_x;
|
wire flush_d_x;
|
||||||
|
|
||||||
wire d_stall;
|
wire d_stall;
|
||||||
|
@ -112,11 +109,8 @@ wire f_mem_size;
|
||||||
assign bus_hsize_i = f_mem_size ? HSIZE_WORD : HSIZE_HWORD;
|
assign bus_hsize_i = f_mem_size ? HSIZE_WORD : HSIZE_HWORD;
|
||||||
|
|
||||||
hazard5_frontend #(
|
hazard5_frontend #(
|
||||||
.EXTENSION_C(EXTENSION_C),
|
|
||||||
.W_ADDR(W_ADDR),
|
|
||||||
.W_DATA(32),
|
|
||||||
.FIFO_DEPTH(2),
|
.FIFO_DEPTH(2),
|
||||||
.RESET_VECTOR(RESET_VECTOR)
|
`include "hazard5_config_inst.vh"
|
||||||
) frontend (
|
) frontend (
|
||||||
.clk (clk),
|
.clk (clk),
|
||||||
.rst_n (rst_n),
|
.rst_n (rst_n),
|
||||||
|
@ -190,13 +184,7 @@ wire [1:0] dx_csr_wtype;
|
||||||
wire dx_csr_w_imm;
|
wire dx_csr_w_imm;
|
||||||
|
|
||||||
hazard5_decode #(
|
hazard5_decode #(
|
||||||
.EXTENSION_C (EXTENSION_C),
|
`include "hazard5_config_inst.vh"
|
||||||
.EXTENSION_M (EXTENSION_M),
|
|
||||||
.HAVE_CSR (CSR_M_MANDATORY || CSR_M_TRAP || CSR_COUNTER),
|
|
||||||
.W_ADDR (W_ADDR),
|
|
||||||
.W_DATA (W_DATA),
|
|
||||||
.RESET_VECTOR (RESET_VECTOR),
|
|
||||||
.W_REGADDR (W_REGADDR)
|
|
||||||
) inst_hazard5_decode (
|
) inst_hazard5_decode (
|
||||||
.clk (clk),
|
.clk (clk),
|
||||||
.rst_n (rst_n),
|
.rst_n (rst_n),
|
||||||
|
@ -399,13 +387,7 @@ wire [W_DATA-1:0] x_csr_rdata;
|
||||||
|
|
||||||
hazard5_csr #(
|
hazard5_csr #(
|
||||||
.XLEN (W_DATA),
|
.XLEN (W_DATA),
|
||||||
.CSR_M_MANDATORY (CSR_M_MANDATORY),
|
`include "hazard5_config_inst.vh"
|
||||||
.CSR_M_TRAP (CSR_M_TRAP),
|
|
||||||
.CSR_COUNTER (CSR_COUNTER),
|
|
||||||
.EXTENSION_C (EXTENSION_C),
|
|
||||||
.EXTENSION_M (EXTENSION_M),
|
|
||||||
.MTVEC_WMASK (MTVEC_WMASK),
|
|
||||||
.MTVEC_INIT (MTVEC_INIT)
|
|
||||||
) inst_hazard5_csr (
|
) inst_hazard5_csr (
|
||||||
.clk (clk),
|
.clk (clk),
|
||||||
.rst_n (rst_n),
|
.rst_n (rst_n),
|
||||||
|
@ -699,7 +681,7 @@ hazard5_regfile_1w2r #(
|
||||||
`else
|
`else
|
||||||
.RESET_REGS(0),
|
.RESET_REGS(0),
|
||||||
`endif
|
`endif
|
||||||
.N_REGS(N_REGS),
|
.N_REGS(32),
|
||||||
.W_DATA(W_DATA)
|
.W_DATA(W_DATA)
|
||||||
) inst_regfile_1w2r (
|
) inst_regfile_1w2r (
|
||||||
.clk (clk),
|
.clk (clk),
|
||||||
|
|
|
@ -76,17 +76,7 @@ wire [W_DATA-1:0] core_rdata_d;
|
||||||
|
|
||||||
|
|
||||||
hazard5_core #(
|
hazard5_core #(
|
||||||
.RESET_VECTOR (RESET_VECTOR),
|
`include "hazard5_config_inst.vh"
|
||||||
.EXTENSION_C (EXTENSION_C),
|
|
||||||
.EXTENSION_M (EXTENSION_M),
|
|
||||||
.MULDIV_UNROLL (MULDIV_UNROLL),
|
|
||||||
.MUL_FAST (MUL_FAST),
|
|
||||||
.CSR_M_MANDATORY (CSR_M_MANDATORY),
|
|
||||||
.CSR_M_TRAP (CSR_M_TRAP),
|
|
||||||
.CSR_COUNTER (CSR_COUNTER),
|
|
||||||
.MTVEC_WMASK (MTVEC_WMASK),
|
|
||||||
.MTVEC_INIT (MTVEC_INIT),
|
|
||||||
.REDUCED_BYPASS (REDUCED_BYPASS)
|
|
||||||
) core (
|
) core (
|
||||||
.clk (clk),
|
.clk (clk),
|
||||||
.rst_n (rst_n),
|
.rst_n (rst_n),
|
||||||
|
|
|
@ -89,17 +89,7 @@ wire [W_DATA-1:0] core_rdata_d;
|
||||||
|
|
||||||
|
|
||||||
hazard5_core #(
|
hazard5_core #(
|
||||||
.RESET_VECTOR (RESET_VECTOR),
|
`include "hazard5_config_inst.vh"
|
||||||
.EXTENSION_C (EXTENSION_C),
|
|
||||||
.EXTENSION_M (EXTENSION_M),
|
|
||||||
.MULDIV_UNROLL (MULDIV_UNROLL),
|
|
||||||
.MUL_FAST (MUL_FAST),
|
|
||||||
.CSR_M_MANDATORY (CSR_M_MANDATORY),
|
|
||||||
.CSR_M_TRAP (CSR_M_TRAP),
|
|
||||||
.CSR_COUNTER (CSR_COUNTER),
|
|
||||||
.MTVEC_WMASK (MTVEC_WMASK),
|
|
||||||
.MTVEC_INIT (MTVEC_INIT),
|
|
||||||
.REDUCED_BYPASS (REDUCED_BYPASS)
|
|
||||||
) core (
|
) core (
|
||||||
.clk (clk),
|
.clk (clk),
|
||||||
.rst_n (rst_n),
|
.rst_n (rst_n),
|
||||||
|
|
|
@ -21,16 +21,10 @@
|
||||||
|
|
||||||
module hazard5_csr #(
|
module hazard5_csr #(
|
||||||
parameter XLEN = 32, // Must be 32
|
parameter XLEN = 32, // Must be 32
|
||||||
parameter CSR_M_MANDATORY = 1, // Include mandatory M-mode CSRs e.g. misa, marchid
|
parameter W_COUNTER = 64, // This *should* be 64, but can be reduced to save gates.
|
||||||
parameter CSR_M_TRAP = 1, // Include M-mode trap setup/handling CSRs
|
|
||||||
parameter CSR_COUNTER = 1, // Include counter/timer CSRs
|
|
||||||
parameter EXTENSION_C = 0, // For misa
|
|
||||||
parameter EXTENSION_M = 0, // For misa
|
|
||||||
parameter MTVEC_WMASK = 32'hfffff000, // Save gates by making trap vector base partially fixed (legal, as it's WARL)
|
|
||||||
parameter MTVEC_INIT = 32'h0,// Initial value of trap vector base
|
|
||||||
parameter W_COUNTER = 64 // This *should* be 64, but can be reduced to save gates.
|
|
||||||
// The full 64 bits is writeable, so high-word increment can
|
// The full 64 bits is writeable, so high-word increment can
|
||||||
// be implemented in software, and a narrower hw counter used
|
// be implemented in software, and a narrower hw counter used
|
||||||
|
`include "hazard5_config.vh"
|
||||||
) (
|
) (
|
||||||
input wire clk,
|
input wire clk,
|
||||||
input wire rst_n,
|
input wire rst_n,
|
||||||
|
|
|
@ -16,13 +16,9 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
module hazard5_decode #(
|
module hazard5_decode #(
|
||||||
parameter EXTENSION_C = 1, // compressed instruction extension
|
`include "hazard5_config.vh"
|
||||||
parameter EXTENSION_M = 1, // mul/div/mod instruction extension
|
,
|
||||||
parameter HAVE_CSR = 0,
|
`include "hazard5_width_const.vh"
|
||||||
parameter W_ADDR = 32,
|
|
||||||
parameter W_DATA = 32,
|
|
||||||
parameter RESET_VECTOR = 32'h0,
|
|
||||||
parameter W_REGADDR = 5
|
|
||||||
) (
|
) (
|
||||||
input wire clk,
|
input wire clk,
|
||||||
input wire rst_n,
|
input wire rst_n,
|
||||||
|
@ -67,15 +63,39 @@ module hazard5_decode #(
|
||||||
output reg [2:0] dx_except
|
output reg [2:0] dx_except
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// TODO TODO factor this out in a cleaner way, e.g. separate out registers and stall logic.
|
|
||||||
|
|
||||||
`include "rv_opcodes.vh"
|
`include "rv_opcodes.vh"
|
||||||
`include "hazard5_ops.vh"
|
`include "hazard5_ops.vh"
|
||||||
|
|
||||||
// ============================================================================
|
localparam HAVE_CSR = CSR_M_MANDATORY || CSR_M_TRAP || CSR_COUNTER;
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Expand compressed instructions
|
||||||
|
|
||||||
|
wire [31:0] d_instr;
|
||||||
|
wire d_instr_is_32bit;
|
||||||
|
wire d_invalid_16bit;
|
||||||
|
reg d_invalid_32bit;
|
||||||
|
wire d_invalid = d_invalid_16bit || d_invalid_32bit;
|
||||||
|
|
||||||
|
hazard5_instr_decompress #(
|
||||||
|
.PASSTHROUGH(!EXTENSION_C)
|
||||||
|
) decomp (
|
||||||
|
.instr_in (fd_cir),
|
||||||
|
.instr_is_32bit (d_instr_is_32bit),
|
||||||
|
.instr_out (d_instr),
|
||||||
|
.invalid (d_invalid_16bit)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Decode various immmediate formats
|
||||||
|
wire [31:0] d_imm_i = {{21{d_instr[31]}}, d_instr[30:20]};
|
||||||
|
wire [31:0] d_imm_s = {{21{d_instr[31]}}, d_instr[30:25], d_instr[11:7]};
|
||||||
|
wire [31:0] d_imm_b = {{20{d_instr[31]}}, d_instr[7], d_instr[30:25], d_instr[11:8], 1'b0};
|
||||||
|
wire [31:0] d_imm_u = {d_instr[31:12], {12{1'b0}}};
|
||||||
|
wire [31:0] d_imm_j = {{12{d_instr[31]}}, d_instr[19:12], d_instr[20], d_instr[30:21], 1'b0};
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
// PC/CIR control
|
// PC/CIR control
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
wire d_starved = ~|fd_cir_vld || fd_cir_vld[0] && d_instr_is_32bit;
|
wire d_starved = ~|fd_cir_vld || fd_cir_vld[0] && d_instr_is_32bit;
|
||||||
assign d_stall = x_stall ||
|
assign d_stall = x_stall ||
|
||||||
|
@ -131,7 +151,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.
|
// If the current CIR is there due to locking, it is a jump which has already had primary effect.
|
||||||
wire d_invalid;
|
|
||||||
wire jump_enable = !d_starved && !cir_lock_prev && !d_invalid;
|
wire jump_enable = !d_starved && !cir_lock_prev && !d_invalid;
|
||||||
reg [W_ADDR-1:0] d_jump_offs;
|
reg [W_ADDR-1:0] d_jump_offs;
|
||||||
|
|
||||||
|
@ -158,35 +177,8 @@ always @ (*) begin
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
|
||||||
// ============================================================================
|
// ----------------------------------------------------------------------------
|
||||||
// Expand compressed instructions
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
wire [31:0] d_instr;
|
|
||||||
wire d_instr_is_32bit;
|
|
||||||
wire d_invalid_16bit;
|
|
||||||
reg d_invalid_32bit;
|
|
||||||
assign d_invalid = d_invalid_16bit || d_invalid_32bit;
|
|
||||||
|
|
||||||
hazard5_instr_decompress #(
|
|
||||||
.PASSTHROUGH(!EXTENSION_C)
|
|
||||||
) decomp (
|
|
||||||
.instr_in (fd_cir),
|
|
||||||
.instr_is_32bit (d_instr_is_32bit),
|
|
||||||
.instr_out (d_instr),
|
|
||||||
.invalid (d_invalid_16bit)
|
|
||||||
);
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// Decode X controls
|
// Decode X controls
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
// Decode various immmediate formats
|
|
||||||
wire [31:0] d_imm_i = {{21{d_instr[31]}}, d_instr[30:20]};
|
|
||||||
wire [31:0] d_imm_s = {{21{d_instr[31]}}, d_instr[30:25], d_instr[11:7]};
|
|
||||||
wire [31:0] d_imm_b = {{20{d_instr[31]}}, d_instr[7], d_instr[30:25], d_instr[11:8], 1'b0};
|
|
||||||
wire [31:0] d_imm_u = {d_instr[31:12], {12{1'b0}}};
|
|
||||||
wire [31:0] d_imm_j = {{12{d_instr[31]}}, d_instr[19:12], d_instr[20], d_instr[30:21], 1'b0};
|
|
||||||
|
|
||||||
// Combinatorials:
|
// Combinatorials:
|
||||||
reg [W_REGADDR-1:0] d_rd;
|
reg [W_REGADDR-1:0] d_rd;
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
module hazard5_frontend #(
|
module hazard5_frontend #(
|
||||||
parameter EXTENSION_C = 1,
|
|
||||||
parameter W_ADDR = 32, // other sizes currently unsupported
|
|
||||||
parameter W_DATA = 32, // other sizes currently unsupported
|
|
||||||
parameter FIFO_DEPTH = 2, // power of 2, >= 1
|
parameter FIFO_DEPTH = 2, // power of 2, >= 1
|
||||||
parameter RESET_VECTOR = 0
|
`include "hazard5_config.vh"
|
||||||
) (
|
) (
|
||||||
input wire clk,
|
input wire clk,
|
||||||
input wire rst_n,
|
input wire rst_n,
|
||||||
|
@ -71,19 +68,31 @@ parameter W_FIFO_LEVEL = $clog2(FIFO_DEPTH + 1);
|
||||||
|
|
||||||
wire jump_now = jump_target_vld && jump_target_rdy;
|
wire jump_now = jump_target_vld && jump_target_rdy;
|
||||||
|
|
||||||
reg [W_DATA-1:0] fifo_mem [0:FIFO_DEPTH];
|
// mem has an extra entry which is equal to next-but-last entry, and valid has
|
||||||
reg [FIFO_DEPTH-1:0] fifo_valid;
|
// an extra entry which is constant-0. These are just there to handle loop
|
||||||
|
// boundary conditions.
|
||||||
|
|
||||||
|
reg [W_DATA-1:0] fifo_mem [0:FIFO_DEPTH];
|
||||||
|
reg [FIFO_DEPTH:0] fifo_valid;
|
||||||
|
|
||||||
|
wire [W_DATA-1:0] fifo_wdata = mem_data;
|
||||||
|
wire [W_DATA-1:0] fifo_rdata = fifo_mem[0];
|
||||||
|
always @ (*) fifo_mem[FIFO_DEPTH] = fifo_wdata;
|
||||||
|
|
||||||
|
wire fifo_full = fifo_valid[FIFO_DEPTH - 1];
|
||||||
|
wire fifo_empty = !fifo_valid[0];
|
||||||
|
wire fifo_almost_full = FIFO_DEPTH == 1 || (!fifo_valid[FIFO_DEPTH - 1] && fifo_valid[FIFO_DEPTH - 2]);
|
||||||
|
|
||||||
wire fifo_push;
|
wire fifo_push;
|
||||||
wire fifo_pop;
|
wire fifo_pop;
|
||||||
|
|
||||||
always @ (posedge clk or negedge rst_n) begin
|
always @ (posedge clk or negedge rst_n) begin
|
||||||
if (!rst_n) begin
|
if (!rst_n) begin
|
||||||
fifo_valid <= {FIFO_DEPTH{1'b0}};
|
fifo_valid <= {FIFO_DEPTH+1{1'b0}};
|
||||||
end else if (jump_now) begin
|
end else if (jump_now) begin
|
||||||
fifo_valid <= {FIFO_DEPTH{1'b0}};
|
fifo_valid[FIFO_DEPTH-1:0] <= {FIFO_DEPTH{1'b0}};
|
||||||
end else if (fifo_push || fifo_pop) begin
|
end else if (fifo_push || fifo_pop) begin
|
||||||
fifo_valid <= ~(~fifo_valid << fifo_push) >> fifo_pop;
|
fifo_valid[FIFO_DEPTH-1:0] <= ~(~fifo_valid << fifo_push) >> fifo_pop;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -96,14 +105,6 @@ always @ (posedge clk) begin: fifo_data_shift
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
wire [W_DATA-1:0] fifo_wdata = mem_data;
|
|
||||||
wire [W_DATA-1:0] fifo_rdata = fifo_mem[0];
|
|
||||||
always @ (*) fifo_mem[FIFO_DEPTH] = fifo_wdata;
|
|
||||||
|
|
||||||
wire fifo_full = fifo_valid[FIFO_DEPTH - 1];
|
|
||||||
wire fifo_empty = !fifo_valid[0];
|
|
||||||
wire fifo_almost_full = FIFO_DEPTH == 1 || (!fifo_valid[FIFO_DEPTH - 1] && fifo_valid[FIFO_DEPTH - 2]);
|
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// Fetch Request + State Logic
|
// Fetch Request + State Logic
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
|
@ -1,9 +1,4 @@
|
||||||
|
|
||||||
localparam W_ALUOP = 4;
|
|
||||||
localparam W_ALUSRC = 2;
|
|
||||||
localparam W_MEMOP = 4;
|
|
||||||
localparam W_BCOND = 2;
|
|
||||||
|
|
||||||
// ALU operation selectors
|
// ALU operation selectors
|
||||||
|
|
||||||
localparam ALUOP_ADD = 4'h0;
|
localparam ALUOP_ADD = 4'h0;
|
||||||
|
@ -52,7 +47,6 @@ localparam CSR_WTYPE_C = 2'h2;
|
||||||
// instructions in the pipeline. These are speculative and can be flushed
|
// instructions in the pipeline. These are speculative and can be flushed
|
||||||
// on e.g. branch mispredict
|
// on e.g. branch mispredict
|
||||||
|
|
||||||
localparam W_EXCEPT = 3;
|
|
||||||
localparam EXCEPT_NONE = 3'h0;
|
localparam EXCEPT_NONE = 3'h0;
|
||||||
localparam EXCEPT_ECALL = 3'h1;
|
localparam EXCEPT_ECALL = 3'h1;
|
||||||
localparam EXCEPT_EBREAK = 3'h2;
|
localparam EXCEPT_EBREAK = 3'h2;
|
||||||
|
@ -63,7 +57,6 @@ localparam EXCEPT_INSTR_FAULT = 3'h6;
|
||||||
|
|
||||||
// Operations for M extension (these are just instr[14:12])
|
// Operations for M extension (these are just instr[14:12])
|
||||||
|
|
||||||
localparam W_MULOP = 3;
|
|
||||||
localparam M_OP_MUL = 3'h0;
|
localparam M_OP_MUL = 3'h0;
|
||||||
localparam M_OP_MULH = 3'h1;
|
localparam M_OP_MULH = 3'h1;
|
||||||
localparam M_OP_MULHSU = 3'h2;
|
localparam M_OP_MULHSU = 3'h2;
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
// These really ought to be localparams, but are occasionally needed for
|
||||||
|
// passing flags around between modules, so are made available as parameters
|
||||||
|
// instead. It's ugly, but better scope hygiene than the preprocessor. These
|
||||||
|
// parameters should not be changed from their default values.
|
||||||
|
|
||||||
|
parameter W_REGADDR = 5,
|
||||||
|
|
||||||
|
parameter W_ALUOP = 4,
|
||||||
|
parameter W_ALUSRC = 2,
|
||||||
|
parameter W_MEMOP = 4,
|
||||||
|
parameter W_BCOND = 2,
|
||||||
|
|
||||||
|
parameter W_EXCEPT = 3,
|
||||||
|
parameter W_MULOP = 3
|
Loading…
Reference in New Issue