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,11 +30,12 @@
 | 
				
			||||||
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,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// mem has an extra entry which is equal to next-but-last entry, and valid has
 | 
				
			||||||
 | 
					// 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 [W_DATA-1:0]   fifo_mem [0:FIFO_DEPTH];
 | 
				
			||||||
reg [FIFO_DEPTH-1:0] fifo_valid;
 | 
					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