2021-01-15 04:37:51 +00:00
|
|
|
///////////////////////////////////////////
|
|
|
|
// controller.sv
|
|
|
|
//
|
2023-01-17 14:02:26 +00:00
|
|
|
// Written: David_Harris@hmc.edu, Sarah.Harris@unlv.edu
|
|
|
|
// Created: 9 January 2021
|
2021-01-15 04:37:51 +00:00
|
|
|
// Modified:
|
|
|
|
//
|
|
|
|
// Purpose: Top level controller module
|
|
|
|
//
|
2023-01-12 12:35:44 +00:00
|
|
|
// Documentation: RISC-V System on Chip Design Chapter 4 (Section 4.1.4, Figure 4.8, Table 4.5)
|
|
|
|
//
|
2023-01-11 23:15:08 +00:00
|
|
|
// A component of the CORE-V-WALLY configurable RISC-V project.
|
2021-01-15 04:37:51 +00:00
|
|
|
//
|
2023-01-10 19:35:20 +00:00
|
|
|
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
|
2021-01-15 04:37:51 +00:00
|
|
|
//
|
2023-01-10 19:35:20 +00:00
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
2021-01-15 04:37:51 +00:00
|
|
|
//
|
2023-01-10 19:35:20 +00:00
|
|
|
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
|
|
|
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
|
|
|
// may obtain a copy of the License at
|
2021-01-15 04:37:51 +00:00
|
|
|
//
|
2023-01-10 19:35:20 +00:00
|
|
|
// https://solderpad.org/licenses/SHL-2.1/
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
|
|
|
// 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.
|
2022-01-07 12:58:40 +00:00
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
2021-01-15 04:37:51 +00:00
|
|
|
|
2021-01-23 15:48:12 +00:00
|
|
|
`include "wally-config.vh"
|
2021-01-15 04:37:51 +00:00
|
|
|
|
|
|
|
|
|
|
|
module controller(
|
2023-01-17 14:02:26 +00:00
|
|
|
input logic clk, reset,
|
2021-01-15 04:37:51 +00:00
|
|
|
// Decode stage control signals
|
2023-01-17 14:02:26 +00:00
|
|
|
input logic StallD, FlushD, // Stall, flush Decode stage
|
|
|
|
input logic [31:0] InstrD, // Instruction in Decode stage
|
|
|
|
output logic [2:0] ImmSrcD, // Type of immediate extension
|
2023-01-17 18:51:44 +00:00
|
|
|
input logic IllegalIEUInstrFaultD, // Illegal IEU instruction
|
|
|
|
output logic IllegalBaseInstrFaultD, // Illegal I-type instruction, or illegal RV32 access to upper 16 registers
|
2023-01-17 14:02:26 +00:00
|
|
|
// Execute stage control signals
|
|
|
|
input logic StallE, FlushE, // Stall, flush Execute stage
|
|
|
|
input logic [1:0] FlagsE, // Comparison flags ({eq, lt})
|
|
|
|
input logic FWriteIntE, // Write integer register, coming from FPU controller
|
|
|
|
output logic PCSrcE, // Select signal to choose next PC (for datapath and Hazard unit)
|
|
|
|
output logic [2:0] ALUControlE, // ALU operation to perform
|
|
|
|
output logic ALUSrcAE, ALUSrcBE, // ALU operands
|
|
|
|
output logic ALUResultSrcE, // Selects result to pass on to Memory stage
|
|
|
|
output logic MemReadE, CSRReadE, // Instruction reads memory, reads a CSR (needed for Hazard unit)
|
|
|
|
output logic [2:0] Funct3E, // Instruction's funct3 field
|
2023-02-09 19:18:54 +00:00
|
|
|
output logic [6:0] Funct7E, // Instruction's funct7 field
|
2023-01-17 14:47:02 +00:00
|
|
|
output logic IntDivE, // Integer divide
|
|
|
|
output logic MDUE, // MDU (multiply/divide) operatio
|
|
|
|
output logic W64E, // RV64 W-type operation
|
|
|
|
output logic JumpE, // jump instruction
|
|
|
|
output logic SCE, // Store Conditional instruction
|
2023-01-17 14:02:26 +00:00
|
|
|
output logic BranchSignedE, // Branch comparison operands are signed (if it's a branch)
|
2021-01-15 04:37:51 +00:00
|
|
|
// Memory stage control signals
|
2023-01-17 14:02:26 +00:00
|
|
|
input logic StallM, FlushM, // Stall, flush Memory stage
|
|
|
|
output logic [1:0] MemRWM, // Mem read/write: MemRWM[1] = 1 for read, MemRWM[0] = 1 for write
|
|
|
|
output logic CSRReadM, CSRWriteM, PrivilegedM, // CSR read, write, or privileged instruction
|
|
|
|
output logic [1:0] AtomicM, // Atomic (AMO) instruction
|
|
|
|
output logic [2:0] Funct3M, // Instruction's funct3 field
|
|
|
|
output logic RegWriteM, // Instruction writes a register (needed for Hazard unit)
|
|
|
|
output logic InvalidateICacheM, FlushDCacheM, // Invalidate I$, flush D$
|
2023-02-10 16:33:10 +00:00
|
|
|
output logic InstrValidD, InstrValidE, InstrValidM, // Instruction is valid
|
|
|
|
|
2023-01-17 14:02:26 +00:00
|
|
|
output logic FWriteIntM, // FPU controller writes integer register file
|
2021-01-15 04:37:51 +00:00
|
|
|
// Writeback stage control signals
|
2023-01-17 14:02:26 +00:00
|
|
|
input logic StallW, FlushW, // Stall, flush Writeback stage
|
|
|
|
output logic RegWriteW, IntDivW, // Instruction writes a register, is an integer divide
|
|
|
|
output logic [2:0] ResultSrcW, // Select source of result to write back to register file
|
2021-01-15 04:37:51 +00:00
|
|
|
// Stall during CSRs
|
2023-01-17 14:47:02 +00:00
|
|
|
output logic CSRWriteFenceM, // CSR write or fence instruction; needs to flush the following instructions
|
2023-01-17 14:02:26 +00:00
|
|
|
output logic StoreStallD // Store (memory write) causes stall
|
2021-01-27 12:46:52 +00:00
|
|
|
);
|
2021-01-15 04:37:51 +00:00
|
|
|
|
2023-01-17 14:02:26 +00:00
|
|
|
logic [6:0] OpD; // Opcode in Decode stage
|
|
|
|
logic [2:0] Funct3D; // Funct3 field in Decode stage
|
|
|
|
logic [6:0] Funct7D; // Funct7 field in Decode stage
|
|
|
|
logic [4:0] Rs1D; // Rs1 source register in Decode stage
|
2021-02-26 22:00:07 +00:00
|
|
|
|
2021-12-08 20:33:53 +00:00
|
|
|
`define CTRLW 23
|
2021-03-11 05:11:31 +00:00
|
|
|
|
2021-01-15 04:37:51 +00:00
|
|
|
// pipelined control signals
|
2023-01-17 14:02:26 +00:00
|
|
|
logic RegWriteD, RegWriteE; // RegWrite (register will be written)
|
|
|
|
logic [2:0] ResultSrcD, ResultSrcE, ResultSrcM; // Select which result to write back to register file
|
|
|
|
logic [1:0] MemRWD, MemRWE; // Store (write to memory)
|
|
|
|
logic JumpD; // Jump instruction
|
|
|
|
logic BranchD, BranchE; // Branch instruction
|
|
|
|
logic ALUOpD; // 0 for address generation, 1 for all other operations (must use Funct3)
|
|
|
|
logic [2:0] ALUControlD; // Determines ALU operation
|
|
|
|
logic ALUSrcAD, ALUSrcBD; // ALU inputs
|
2023-01-17 14:47:02 +00:00
|
|
|
logic ALUResultSrcD, W64D, MDUD; // ALU result, is RV64 W-type, is multiply/divide instruction
|
|
|
|
logic CSRZeroSrcD; // Ignore setting and clearing zeros to CSR
|
2023-01-17 14:02:26 +00:00
|
|
|
logic CSRReadD; // CSR read instruction
|
2023-01-17 14:47:02 +00:00
|
|
|
logic [1:0] AtomicD; // Atomic (AMO) instruction
|
|
|
|
logic FenceXD; // Fence instruction
|
2023-01-17 14:02:26 +00:00
|
|
|
logic InvalidateICacheD, FlushDCacheD;// Invalidate I$, flush D$
|
|
|
|
logic CSRWriteD, CSRWriteE; // CSR write
|
|
|
|
logic PrivilegedD, PrivilegedE; // Privileged instruction
|
|
|
|
logic InvalidateICacheE, FlushDCacheE;// Invalidate I$, flush D$
|
|
|
|
logic [`CTRLW-1:0] ControlsD; // Main Instruction Decoder control signals
|
|
|
|
logic SubArithD; // TRUE for R-type subtracts and sra, slt, sltu
|
|
|
|
logic subD, sraD, sltD, sltuD; // Indicates if is one of these instructions
|
|
|
|
logic BranchTakenE; // Branch is taken
|
|
|
|
logic eqE, ltE; // Comparator outputs
|
|
|
|
logic unused;
|
|
|
|
logic BranchFlagE; // Branch flag to use (chosen between eq or lt)
|
|
|
|
logic IEURegWriteE; // Register write
|
2023-01-17 18:51:44 +00:00
|
|
|
logic IllegalERegAdrD; // RV32E attempts to write upper 16 registers
|
|
|
|
logic [1:0] AtomicE; // Atomic instruction
|
2023-01-17 14:02:26 +00:00
|
|
|
logic FenceD, FenceE, FenceM; // Fence instruction
|
2023-01-17 18:51:44 +00:00
|
|
|
logic SFenceVmaD; // sfence.vma instruction
|
2023-01-17 14:02:26 +00:00
|
|
|
logic IntDivM; // Integer divide instruction
|
2022-06-02 16:37:59 +00:00
|
|
|
|
2021-12-08 20:33:53 +00:00
|
|
|
|
2021-02-26 22:00:07 +00:00
|
|
|
// Extract fields
|
|
|
|
assign OpD = InstrD[6:0];
|
|
|
|
assign Funct3D = InstrD[14:12];
|
|
|
|
assign Funct7D = InstrD[31:25];
|
|
|
|
assign Rs1D = InstrD[19:15];
|
2021-01-15 04:37:51 +00:00
|
|
|
|
|
|
|
// Main Instruction Decoder
|
2022-01-05 14:35:25 +00:00
|
|
|
always_comb
|
|
|
|
case(OpD)
|
2022-01-07 04:30:00 +00:00
|
|
|
// RegWrite_ImmSrc_ALUSrc_MemRW_ResultSrc_Branch_ALUOp_Jump_ALUResultSrc_W64_CSRRead_Privileged_Fence_MDU_Atomic_Illegal
|
2023-01-17 14:02:26 +00:00
|
|
|
7'b0000000: ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // Illegal instruction
|
|
|
|
7'b0000011: ControlsD = `CTRLW'b1_000_01_10_001_0_0_0_0_0_0_0_0_0_00_0; // lw
|
|
|
|
7'b0000111: ControlsD = `CTRLW'b0_000_01_10_001_0_0_0_0_0_0_0_0_0_00_0; // flw - only legal if FP supported
|
|
|
|
7'b0001111: if (`ZIFENCEI_SUPPORTED)
|
|
|
|
ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_1_0_00_0; // fence
|
2022-12-20 23:34:11 +00:00
|
|
|
else
|
2023-01-17 14:02:26 +00:00
|
|
|
ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_0; // fence treated as nop
|
|
|
|
7'b0010011: ControlsD = `CTRLW'b1_000_01_00_000_0_1_0_0_0_0_0_0_0_00_0; // I-type ALU
|
|
|
|
7'b0010111: ControlsD = `CTRLW'b1_100_11_00_000_0_0_0_0_0_0_0_0_0_00_0; // auipc
|
2022-01-05 14:35:25 +00:00
|
|
|
7'b0011011: if (`XLEN == 64)
|
2023-01-17 14:02:26 +00:00
|
|
|
ControlsD = `CTRLW'b1_000_01_00_000_0_1_0_0_1_0_0_0_0_00_0; // IW-type ALU for RV64i
|
2022-01-05 14:35:25 +00:00
|
|
|
else
|
2023-01-17 14:02:26 +00:00
|
|
|
ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // Non-implemented instruction
|
|
|
|
7'b0100011: ControlsD = `CTRLW'b0_001_01_01_000_0_0_0_0_0_0_0_0_0_00_0; // sw
|
|
|
|
7'b0100111: ControlsD = `CTRLW'b0_001_01_01_000_0_0_0_0_0_0_0_0_0_00_0; // fsw - only legal if FP supported
|
2022-01-05 14:35:25 +00:00
|
|
|
7'b0101111: if (`A_SUPPORTED) begin
|
|
|
|
if (InstrD[31:27] == 5'b00010)
|
|
|
|
ControlsD = `CTRLW'b1_000_00_10_001_0_0_0_0_0_0_0_0_0_01_0; // lr
|
|
|
|
else if (InstrD[31:27] == 5'b00011)
|
|
|
|
ControlsD = `CTRLW'b1_101_01_01_100_0_0_0_0_0_0_0_0_0_01_0; // sc
|
|
|
|
else
|
2023-01-17 14:02:26 +00:00
|
|
|
ControlsD = `CTRLW'b1_101_01_11_001_0_0_0_0_0_0_0_0_0_10_0; // amo
|
2022-01-05 14:35:25 +00:00
|
|
|
end else
|
2023-01-17 14:02:26 +00:00
|
|
|
ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // Non-implemented instruction
|
2023-02-12 05:22:33 +00:00
|
|
|
7'b0110011: if (Funct7D == 7'b0000000 | Funct7D == 7'b0100000)
|
2023-01-17 14:02:26 +00:00
|
|
|
ControlsD = `CTRLW'b1_000_00_00_000_0_1_0_0_0_0_0_0_0_00_0; // R-type
|
2022-01-05 14:35:25 +00:00
|
|
|
else if (Funct7D == 7'b0000001 & `M_SUPPORTED)
|
2023-01-17 14:02:26 +00:00
|
|
|
ControlsD = `CTRLW'b1_000_00_00_011_0_0_0_0_0_0_0_0_1_00_0; // Multiply/divide
|
2022-01-05 14:35:25 +00:00
|
|
|
else
|
2023-01-17 14:02:26 +00:00
|
|
|
ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // Non-implemented instruction
|
|
|
|
7'b0110111: ControlsD = `CTRLW'b1_100_01_00_000_0_0_0_1_0_0_0_0_0_00_0; // lui
|
2022-01-05 14:35:25 +00:00
|
|
|
7'b0111011: if ((Funct7D == 7'b0000000 | Funct7D == 7'b0100000) & `XLEN == 64)
|
2023-01-17 14:02:26 +00:00
|
|
|
ControlsD = `CTRLW'b1_000_00_00_000_0_1_0_0_1_0_0_0_0_00_0; // R-type W instructions for RV64i
|
2022-01-05 14:35:25 +00:00
|
|
|
else if (Funct7D == 7'b0000001 & `M_SUPPORTED & `XLEN == 64)
|
2023-01-17 14:02:26 +00:00
|
|
|
ControlsD = `CTRLW'b1_000_00_00_011_0_0_0_0_1_0_0_0_1_00_0; // W-type Multiply/Divide
|
2022-01-05 14:35:25 +00:00
|
|
|
else
|
2023-02-12 05:22:33 +00:00
|
|
|
ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // Non-implemented instruction
|
2023-01-17 14:02:26 +00:00
|
|
|
7'b1100011: ControlsD = `CTRLW'b0_010_11_00_000_1_0_0_0_0_0_0_0_0_00_0; // branches
|
|
|
|
7'b1100111: ControlsD = `CTRLW'b1_000_01_00_000_0_0_1_1_0_0_0_0_0_00_0; // jalr
|
|
|
|
7'b1101111: ControlsD = `CTRLW'b1_011_11_00_000_0_0_1_1_0_0_0_0_0_00_0; // jal
|
2022-02-12 05:50:34 +00:00
|
|
|
7'b1110011: if (`ZICSR_SUPPORTED) begin
|
|
|
|
if (Funct3D == 3'b000)
|
2023-01-17 14:02:26 +00:00
|
|
|
ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_1_0_0_00_0; // privileged; decoded further in priveleged modules
|
2022-02-12 05:50:34 +00:00
|
|
|
else
|
2023-01-17 14:02:26 +00:00
|
|
|
ControlsD = `CTRLW'b1_000_00_00_010_0_0_0_0_0_1_0_0_0_00_0; // csrs
|
2022-02-12 05:50:34 +00:00
|
|
|
end else
|
2023-01-17 14:02:26 +00:00
|
|
|
ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // non-implemented instruction
|
|
|
|
default: ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // non-implemented instruction
|
2022-01-05 14:35:25 +00:00
|
|
|
endcase
|
2021-01-15 04:37:51 +00:00
|
|
|
|
2023-01-17 14:02:26 +00:00
|
|
|
// Unswizzle control bits
|
|
|
|
// Squash control signals if coming from an illegal compressed instruction
|
2022-01-17 14:42:59 +00:00
|
|
|
// On RV32E, can't write to upper 16 registers. Checking reads to upper 16 is more costly so disregard them.
|
2022-02-06 01:22:40 +00:00
|
|
|
assign IllegalERegAdrD = `E_SUPPORTED & `ZICSR_SUPPORTED & ControlsD[`CTRLW-1] & InstrD[11];
|
2022-01-17 14:42:59 +00:00
|
|
|
assign IllegalBaseInstrFaultD = ControlsD[0] | IllegalERegAdrD;
|
2021-01-15 04:37:51 +00:00
|
|
|
assign {RegWriteD, ImmSrcD, ALUSrcAD, ALUSrcBD, MemRWD,
|
2021-12-08 20:33:53 +00:00
|
|
|
ResultSrcD, BranchD, ALUOpD, JumpD, ALUResultSrcD, W64D, CSRReadD,
|
2022-12-15 15:53:35 +00:00
|
|
|
PrivilegedD, FenceXD, MDUD, AtomicD, unused} = IllegalIEUInstrFaultD ? `CTRLW'b0 : ControlsD;
|
2022-12-20 23:34:11 +00:00
|
|
|
|
2021-01-15 04:37:51 +00:00
|
|
|
|
2021-02-26 22:00:07 +00:00
|
|
|
assign CSRZeroSrcD = InstrD[14] ? (InstrD[19:15] == 0) : (Rs1D == 0); // Is a CSR instruction using zero as the source?
|
2023-01-17 14:02:26 +00:00
|
|
|
assign CSRWriteD = CSRReadD & !(CSRZeroSrcD & InstrD[13]); // Don't write if setting or clearing zeros
|
2022-12-15 15:53:35 +00:00
|
|
|
assign SFenceVmaD = PrivilegedD & (InstrD[31:25] == 7'b0001001);
|
|
|
|
assign FenceD = SFenceVmaD | FenceXD; // possible sfence.vma or fence.i
|
2021-02-26 22:00:07 +00:00
|
|
|
|
2023-02-12 05:22:33 +00:00
|
|
|
// ALU Decoding is lazy, only using func7[5] to distinguish add/sub and srl/sra
|
|
|
|
assign sltD = (Funct3D == 3'b010);
|
|
|
|
assign sltuD = (Funct3D == 3'b011);
|
|
|
|
assign subD = (Funct3D == 3'b000 & Funct7D[5] & OpD[5]); // OpD[5] needed to distinguish sub from addi
|
|
|
|
assign sraD = (Funct3D == 3'b101 & Funct7D[5]);
|
|
|
|
assign SubArithD = ALUOpD & (subD | sraD | sltD | sltuD); // TRUE for R-type subtracts and sra, slt, sltu
|
|
|
|
assign ALUControlD = {W64D, SubArithD, ALUOpD};
|
2021-09-15 17:14:00 +00:00
|
|
|
|
|
|
|
// Fences
|
|
|
|
// Ordinary fence is presently a nop
|
2023-01-17 14:02:26 +00:00
|
|
|
// fence.i flushes the D$ and invalidates the I$ if Zifencei is supported and I$ is implemented
|
2023-01-29 02:52:00 +00:00
|
|
|
if (`ZIFENCEI_SUPPORTED & `ICACHE_SUPPORTED) begin:fencei
|
2022-01-05 14:35:25 +00:00
|
|
|
logic FenceID;
|
2022-12-15 15:53:35 +00:00
|
|
|
assign FenceID = FenceXD & (Funct3D == 3'b001); // is it a FENCE.I instruction?
|
2022-01-05 14:35:25 +00:00
|
|
|
assign InvalidateICacheD = FenceID;
|
|
|
|
assign FlushDCacheD = FenceID;
|
|
|
|
end else begin:fencei
|
|
|
|
assign InvalidateICacheD = 0;
|
|
|
|
assign FlushDCacheD = 0;
|
|
|
|
end
|
2021-09-15 17:14:00 +00:00
|
|
|
|
2021-06-02 14:03:19 +00:00
|
|
|
// Decocde stage pipeline control register
|
|
|
|
flopenrc #(1) controlregD(clk, reset, FlushD, ~StallD, 1'b1, InstrValidD);
|
|
|
|
|
2021-01-15 04:37:51 +00:00
|
|
|
// Execute stage pipeline control register and logic
|
2023-02-12 05:22:33 +00:00
|
|
|
flopenrc #(28) controlregE(clk, reset, FlushE, ~StallE,
|
|
|
|
{RegWriteD, ResultSrcD, MemRWD, JumpD, BranchD, ALUControlD, ALUSrcAD, ALUSrcBD, ALUResultSrcD, CSRReadD, CSRWriteD, PrivilegedD, Funct3D, W64D, MDUD, AtomicD, InvalidateICacheD, FlushDCacheD, FenceD, InstrValidD},
|
|
|
|
{IEURegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUControlE, ALUSrcAE, ALUSrcBE, ALUResultSrcE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, W64E, MDUE, AtomicE, InvalidateICacheE, FlushDCacheE, FenceE, InstrValidE});
|
2021-01-15 04:37:51 +00:00
|
|
|
|
|
|
|
// Branch Logic
|
2023-01-07 13:42:34 +00:00
|
|
|
// The comparator handles both signed and unsigned branches using BranchSignedE
|
|
|
|
// Hence, only eq and lt flags are needed
|
2022-06-21 20:30:33 +00:00
|
|
|
assign BranchSignedE = ~(Funct3E[2:1] == 2'b11);
|
|
|
|
assign {eqE, ltE} = FlagsE;
|
2023-01-07 13:42:34 +00:00
|
|
|
mux2 #(1) branchflagmux(eqE, ltE, Funct3E[2], BranchFlagE);
|
2021-12-08 20:33:53 +00:00
|
|
|
assign BranchTakenE = BranchFlagE ^ Funct3E[0];
|
2021-01-15 04:37:51 +00:00
|
|
|
assign PCSrcE = JumpE | BranchE & BranchTakenE;
|
|
|
|
|
2021-12-19 21:53:45 +00:00
|
|
|
// Other execute stage controller signals
|
2021-06-25 11:18:38 +00:00
|
|
|
assign MemReadE = MemRWE[1];
|
|
|
|
assign SCE = (ResultSrcE == 3'b100);
|
2021-12-18 13:36:32 +00:00
|
|
|
assign RegWriteE = IEURegWriteE | FWriteIntE; // IRF register writes could come from IEU or FPU controllers
|
2023-01-11 19:06:37 +00:00
|
|
|
assign IntDivE = MDUE & Funct3E[2]; // Integer division operation
|
2021-01-15 04:37:51 +00:00
|
|
|
|
|
|
|
// Memory stage pipeline control register
|
2022-12-15 01:03:13 +00:00
|
|
|
flopenrc #(20) controlregM(clk, reset, FlushM, ~StallM,
|
2023-01-11 19:06:37 +00:00
|
|
|
{RegWriteE, ResultSrcE, MemRWE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, FWriteIntE, AtomicE, InvalidateICacheE, FlushDCacheE, FenceE, InstrValidE, IntDivE},
|
|
|
|
{RegWriteM, ResultSrcM, MemRWM, CSRReadM, CSRWriteM, PrivilegedM, Funct3M, FWriteIntM, AtomicM, InvalidateICacheM, FlushDCacheM, FenceM, InstrValidM, IntDivM});
|
2021-01-15 04:37:51 +00:00
|
|
|
|
|
|
|
// Writeback stage pipeline control register
|
2022-12-15 01:03:13 +00:00
|
|
|
flopenrc #(5) controlregW(clk, reset, FlushW, ~StallW,
|
2023-01-11 19:06:37 +00:00
|
|
|
{RegWriteM, ResultSrcM, IntDivM},
|
|
|
|
{RegWriteW, ResultSrcW, IntDivW});
|
2021-01-15 04:37:51 +00:00
|
|
|
|
2022-12-15 15:53:35 +00:00
|
|
|
// Flush F, D, and E stages on a CSR write or Fence.I or SFence.VMA
|
|
|
|
assign CSRWriteFenceM = CSRWriteM | FenceM;
|
2023-01-17 14:02:26 +00:00
|
|
|
// assign CSRWriteFencePendingDEM = CSRWriteD | CSRWriteE | CSRWriteM | FenceD | FenceE | FenceM;
|
2021-07-13 18:20:50 +00:00
|
|
|
|
2022-09-21 20:02:34 +00:00
|
|
|
// the synchronous DTIM cannot read immediately after write
|
|
|
|
// a cache cannot read or write immediately after a write
|
2023-01-29 02:52:00 +00:00
|
|
|
assign StoreStallD = MemRWE[0] & ((MemRWD[1] | (MemRWD[0] & `DCACHE_SUPPORTED)) | (|AtomicD));
|
2023-02-12 05:22:33 +00:00
|
|
|
endmodule
|