mirror of
				https://github.com/openhwgroup/cvw
				synced 2025-02-11 06:05:49 +00:00 
			
		
		
		
	Merge branch 'main' of github.com:davidharrishmc/riscv-wally into main
This commit is contained in:
		
						commit
						f69b84fe31
					
				@ -63,9 +63,9 @@ add wave -divider
 | 
			
		||||
#add wave -hex /testbench/dut/hart/ifu/PCM
 | 
			
		||||
#add wave -hex /testbench/dut/hart/ifu/InstrM
 | 
			
		||||
add wave /testbench/InstrMName
 | 
			
		||||
add wave /testbench/dut/dmem/dtim/memwrite
 | 
			
		||||
add wave -hex /testbench/dut/dmem/AdrM
 | 
			
		||||
add wave -hex /testbench/dut/dmem/WriteDataM
 | 
			
		||||
add wave /testbench/dut/uncore/dtim/memwrite
 | 
			
		||||
add wave -hex /testbench/dut/uncore/AdrM
 | 
			
		||||
add wave -hex /testbench/dut/uncore/WriteDataM
 | 
			
		||||
add wave -divider
 | 
			
		||||
add wave -hex /testbench/dut/hart/ifu/PCW
 | 
			
		||||
add wave /testbench/InstrWName
 | 
			
		||||
 | 
			
		||||
@ -46,6 +46,7 @@ module controller(
 | 
			
		||||
  output logic       MemReadE,  // for Hazard Unit
 | 
			
		||||
  // Memory stage control signals
 | 
			
		||||
  input  logic       FlushM,
 | 
			
		||||
  input  logic       DataMisalignedM,
 | 
			
		||||
  output logic [1:0] MemRWM,
 | 
			
		||||
  output logic       CSRWriteM, PrivilegedM, 
 | 
			
		||||
  output logic [2:0] Funct3M,
 | 
			
		||||
@ -110,7 +111,7 @@ module controller(
 | 
			
		||||
  assign {RegWriteD, ImmSrcD, ALUSrcAD, ALUSrcBD, MemRWD,
 | 
			
		||||
          ResultSrcD, BranchD, ALUOpD, JumpD, TargetSrcD, W64D, CSRWriteD,
 | 
			
		||||
          PrivilegedD} = ControlsD[18:1] & ~IllegalIEUInstrFaultD;
 | 
			
		||||
          // *** move Privileged, CSRwrite
 | 
			
		||||
          // *** move Privileged, CSRwrite??  Or move controller out of IEU into datapath and handle all instructions
 | 
			
		||||
 | 
			
		||||
  // ALU Decoding
 | 
			
		||||
  assign sltD = (Funct3D == 3'b010);
 | 
			
		||||
 | 
			
		||||
@ -45,10 +45,10 @@ module datapath (
 | 
			
		||||
  input  logic             FlushM,
 | 
			
		||||
  input  logic [2:0]       Funct3M,
 | 
			
		||||
  input  logic [`XLEN-1:0] CSRReadValM,
 | 
			
		||||
  input  logic [`XLEN-1:0] ReadDataExtM,
 | 
			
		||||
  input  logic [`XLEN-1:0] ReadDataM,
 | 
			
		||||
  input  logic             RetM, TrapM,
 | 
			
		||||
  output logic [`XLEN-1:0] SrcAM,
 | 
			
		||||
  output logic [`XLEN-1:0] WriteDataFullM, DataAdrM,
 | 
			
		||||
  output logic [`XLEN-1:0] WriteDataM, DataAdrM,
 | 
			
		||||
  // Writeback stage signals
 | 
			
		||||
  input  logic             FlushW,
 | 
			
		||||
  input  logic             RegWriteW, 
 | 
			
		||||
@ -106,12 +106,12 @@ module datapath (
 | 
			
		||||
  floprc #(`XLEN) SrcAMReg(clk, reset, FlushM, SrcAE, SrcAM);
 | 
			
		||||
  floprc #(`XLEN) ALUResultMReg(clk, reset, FlushM, ALUResultE, ALUResultM);
 | 
			
		||||
  assign DataAdrM = ALUResultM;
 | 
			
		||||
  floprc #(`XLEN) WriteDataMReg(clk, reset, FlushM, WriteDataE, WriteDataFullM);
 | 
			
		||||
  floprc #(`XLEN) WriteDataMReg(clk, reset, FlushM, WriteDataE, WriteDataM);
 | 
			
		||||
  floprc #(5)    RdMEg(clk, reset, FlushM, RdE, RdM);
 | 
			
		||||
  
 | 
			
		||||
  // Writeback stage pipeline register and logic
 | 
			
		||||
  floprc #(`XLEN) ALUResultWReg(clk, reset, FlushW, ALUResultM, ALUResultW);
 | 
			
		||||
  floprc #(`XLEN) ReadDataWReg(clk, reset, FlushW, ReadDataExtM, ReadDataW);
 | 
			
		||||
  floprc #(`XLEN) ReadDataWReg(clk, reset, FlushW, ReadDataM, ReadDataW);
 | 
			
		||||
  floprc #(`XLEN) CSRValWReg(clk, reset, FlushW, CSRReadValM, CSRValW);
 | 
			
		||||
  floprc #(5)    RdWEg(clk, reset, FlushW, RdM, RdW);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -29,19 +29,40 @@
 | 
			
		||||
 | 
			
		||||
module dcu (
 | 
			
		||||
  input  logic [1:0]      MemRWM,
 | 
			
		||||
  input  logic [`XLEN-1:0] ReadDataM,
 | 
			
		||||
  output logic [1:0]      MemRWdcuoutM,
 | 
			
		||||
  output logic            DataMisalignedM,
 | 
			
		||||
 | 
			
		||||
  input  logic [`XLEN-1:0] DataAdrM,
 | 
			
		||||
  input  logic [2:0]      Funct3M,
 | 
			
		||||
  output logic [`XLEN-1:0] ReadDataExtM,
 | 
			
		||||
  input  logic [`XLEN-1:0] WriteDataFullM,
 | 
			
		||||
  output logic [`XLEN-1:0] WriteDataM,
 | 
			
		||||
  output logic [7:0]      ByteMaskM,
 | 
			
		||||
/*  output  logic [`XLEN-1:0] ReadDataM,
 | 
			
		||||
  input logic [`XLEN-1:0] WriteDataM, */
 | 
			
		||||
  // faults
 | 
			
		||||
  input  logic            DataAccessFaultM,
 | 
			
		||||
  output logic            LoadMisalignedFaultM, LoadAccessFaultM,
 | 
			
		||||
  output logic            StoreMisalignedFaultM, StoreAccessFaultM
 | 
			
		||||
);
 | 
			
		||||
                  
 | 
			
		||||
  memdp memdp(.*);
 | 
			
		||||
//  memdp memdp(.*);
 | 
			
		||||
 | 
			
		||||
	// Determine if an Unaligned access is taking place
 | 
			
		||||
	always_comb
 | 
			
		||||
		case(Funct3M[1:0]) 
 | 
			
		||||
		  2'b00:  DataMisalignedM = 0;                 // lb, sb, lbu
 | 
			
		||||
		  2'b01:  DataMisalignedM = DataAdrM[0];           // lh, sh, lhu
 | 
			
		||||
		  2'b10:  DataMisalignedM = DataAdrM[1] | DataAdrM[0]; // lw, sw, flw, fsw, lwu
 | 
			
		||||
		  2'b11:  DataMisalignedM = |DataAdrM[2:0];        // ld, sd, fld, fsd
 | 
			
		||||
		endcase 
 | 
			
		||||
 | 
			
		||||
  // Squash unaligned data accesses
 | 
			
		||||
  // *** this is also the place to squash if the cache is hit
 | 
			
		||||
  assign MemRWdcuoutM = MemRWM & {2{~DataMisalignedM}};
 | 
			
		||||
 | 
			
		||||
  // Determine if address is valid
 | 
			
		||||
  assign LoadMisalignedFaultM = DataMisalignedM & MemRWM[1];
 | 
			
		||||
  assign LoadAccessFaultM = DataAccessFaultM & MemRWM[0];
 | 
			
		||||
  assign StoreMisalignedFaultM = DataMisalignedM & MemRWM[0];
 | 
			
		||||
  assign StoreAccessFaultM = DataAccessFaultM & MemRWM[0];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -28,9 +28,9 @@
 | 
			
		||||
module dtim (
 | 
			
		||||
  input  logic            clk, 
 | 
			
		||||
  input  logic [1:0]      MemRWdtimM,
 | 
			
		||||
  input  logic [7:0]      ByteMaskM,
 | 
			
		||||
//  input  logic [7:0]      ByteMaskM,
 | 
			
		||||
  input  logic [18:0]     AdrM, 
 | 
			
		||||
  input  logic [`XLEN-1:0] WriteDataM,
 | 
			
		||||
  input  logic [`XLEN-1:0] MaskedWriteDataM,
 | 
			
		||||
  output logic [`XLEN-1:0] RdTimM);
 | 
			
		||||
 | 
			
		||||
  logic [`XLEN-1:0] RAM[0:65535];
 | 
			
		||||
@ -54,7 +54,7 @@ module dtim (
 | 
			
		||||
  // UInstantiate a byte-writable memory here if possible
 | 
			
		||||
  // and drop tihs masking logic.  Otherwise, use the masking
 | 
			
		||||
  // from dmem
 | 
			
		||||
  generate
 | 
			
		||||
  /*generate
 | 
			
		||||
 | 
			
		||||
    if (`XLEN==64) begin
 | 
			
		||||
      always_comb begin
 | 
			
		||||
@ -81,6 +81,15 @@ module dtim (
 | 
			
		||||
    always_ff @(posedge clk)
 | 
			
		||||
      if (memwrite) RAM[AdrM[17:2]] <= write;  
 | 
			
		||||
    end
 | 
			
		||||
  endgenerate */
 | 
			
		||||
  generate
 | 
			
		||||
    if (`XLEN == 64) begin
 | 
			
		||||
      always_ff @(posedge clk)
 | 
			
		||||
        if (memwrite) RAM[AdrM[17:3]] <= MaskedWriteDataM;  
 | 
			
		||||
    end else begin
 | 
			
		||||
      always_ff @(posedge clk)
 | 
			
		||||
        if (memwrite) RAM[AdrM[17:2]] <= MaskedWriteDataM;  
 | 
			
		||||
    end
 | 
			
		||||
  endgenerate
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -28,8 +28,9 @@
 | 
			
		||||
module ieu (
 | 
			
		||||
  input  logic            clk, reset,
 | 
			
		||||
  output logic [1:0]      MemRWM,
 | 
			
		||||
  output logic [`XLEN-1:0] DataAdrM, WriteDataFullM,
 | 
			
		||||
  input  logic [`XLEN-1:0] ReadDataExtM,
 | 
			
		||||
  output logic [`XLEN-1:0] DataAdrM, WriteDataM,
 | 
			
		||||
  input  logic [`XLEN-1:0] ReadDataM,
 | 
			
		||||
  input  logic            DataMisalignedM,
 | 
			
		||||
  input  logic            DataAccessFaultM,
 | 
			
		||||
  input  logic [1:0]      ForwardAE, ForwardBE,
 | 
			
		||||
  input  logic            StallD, FlushD, FlushE, FlushM, FlushW,
 | 
			
		||||
@ -39,6 +40,7 @@ module ieu (
 | 
			
		||||
  output logic        RegWriteW,
 | 
			
		||||
  output logic        CSRWriteM, PrivilegedM,
 | 
			
		||||
  output logic        CSRWritePendingDEM,
 | 
			
		||||
  output logic [2:0]       Funct3M,
 | 
			
		||||
  output logic [`XLEN-1:0] SrcAM,
 | 
			
		||||
  output logic [`XLEN-1:0] PCTargetE,
 | 
			
		||||
  input  logic [31:0] InstrD,
 | 
			
		||||
@ -56,7 +58,6 @@ module ieu (
 | 
			
		||||
  logic [2:0]  FlagsE;
 | 
			
		||||
  logic [4:0]  ALUControlE;
 | 
			
		||||
  logic        ALUSrcAE, ALUSrcBE;
 | 
			
		||||
  logic [2:0]  Funct3M;
 | 
			
		||||
  logic [1:0]  ResultSrcW;
 | 
			
		||||
 | 
			
		||||
  logic       TargetSrcE;
 | 
			
		||||
 | 
			
		||||
@ -1,190 +0,0 @@
 | 
			
		||||
///////////////////////////////////////////
 | 
			
		||||
// memdp.sv
 | 
			
		||||
//
 | 
			
		||||
// Written: David_Harris@hmc.edu 9 January 2021
 | 
			
		||||
// Modified: 
 | 
			
		||||
//
 | 
			
		||||
// Purpose: Memory datapath for subword accesses
 | 
			
		||||
// 
 | 
			
		||||
// A component of the Wally configurable RISC-V project.
 | 
			
		||||
// 
 | 
			
		||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
 | 
			
		||||
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, 
 | 
			
		||||
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software 
 | 
			
		||||
// is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
 | 
			
		||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 
 | 
			
		||||
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT 
 | 
			
		||||
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
///////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
`include "wally-config.vh"
 | 
			
		||||
 | 
			
		||||
module memdp (
 | 
			
		||||
  input  logic [1:0]      MemRWM,
 | 
			
		||||
  input  logic [`XLEN-1:0] ReadDataM,
 | 
			
		||||
  input  logic [`XLEN-1:0] DataAdrM,
 | 
			
		||||
  input  logic [2:0]      Funct3M,
 | 
			
		||||
  output logic [`XLEN-1:0] ReadDataExtM,
 | 
			
		||||
  input  logic [`XLEN-1:0] WriteDataFullM,
 | 
			
		||||
  output logic [`XLEN-1:0] WriteDataM,
 | 
			
		||||
  output logic [7:0]      ByteMaskM,
 | 
			
		||||
  input  logic            DataAccessFaultM,
 | 
			
		||||
  output logic            LoadMisalignedFaultM, LoadAccessFaultM,
 | 
			
		||||
  output logic            StoreMisalignedFaultM, StoreAccessFaultM
 | 
			
		||||
);
 | 
			
		||||
                  
 | 
			
		||||
  logic [7:0]  bytM;
 | 
			
		||||
  logic [15:0] HalfwordM;
 | 
			
		||||
  logic        UnalignedM;
 | 
			
		||||
  
 | 
			
		||||
  generate
 | 
			
		||||
    if (`XLEN == 64) begin
 | 
			
		||||
      // bytMe mux
 | 
			
		||||
      always_comb
 | 
			
		||||
      case(DataAdrM[2:0])
 | 
			
		||||
        3'b000: bytM = ReadDataM[7:0];
 | 
			
		||||
        3'b001: bytM = ReadDataM[15:8];
 | 
			
		||||
        3'b010: bytM = ReadDataM[23:16];
 | 
			
		||||
        3'b011: bytM = ReadDataM[31:24];
 | 
			
		||||
        3'b100: bytM = ReadDataM[39:32];
 | 
			
		||||
        3'b101: bytM = ReadDataM[47:40];
 | 
			
		||||
        3'b110: bytM = ReadDataM[55:48];
 | 
			
		||||
        3'b111: bytM = ReadDataM[63:56];
 | 
			
		||||
      endcase
 | 
			
		||||
    
 | 
			
		||||
      // halfword mux
 | 
			
		||||
      always_comb
 | 
			
		||||
      case(DataAdrM[2:1])
 | 
			
		||||
        2'b00: HalfwordM = ReadDataM[15:0];
 | 
			
		||||
        2'b01: HalfwordM = ReadDataM[31:16];
 | 
			
		||||
        2'b10: HalfwordM = ReadDataM[47:32];
 | 
			
		||||
        2'b11: HalfwordM = ReadDataM[63:48];
 | 
			
		||||
      endcase
 | 
			
		||||
      
 | 
			
		||||
      logic [31:0] word;
 | 
			
		||||
      
 | 
			
		||||
      always_comb
 | 
			
		||||
        case(DataAdrM[2])
 | 
			
		||||
          1'b0: word = ReadDataM[31:0];
 | 
			
		||||
          1'b1: word = ReadDataM[63:32];
 | 
			
		||||
        endcase
 | 
			
		||||
 | 
			
		||||
      // sign extension
 | 
			
		||||
      always_comb
 | 
			
		||||
      case(Funct3M) 
 | 
			
		||||
        3'b000:  ReadDataExtM = {{56{bytM[7]}}, bytM};                  // lb
 | 
			
		||||
        3'b001:  ReadDataExtM = {{48{HalfwordM[15]}}, HalfwordM[15:0]}; // lh 
 | 
			
		||||
        3'b010:  ReadDataExtM = {{32{word[31]}}, word[31:0]};           // lw
 | 
			
		||||
        3'b011:  ReadDataExtM = ReadDataM;                              // ld
 | 
			
		||||
        3'b100:  ReadDataExtM = {56'b0, bytM[7:0]};                     // lbu
 | 
			
		||||
        3'b101:  ReadDataExtM = {48'b0, HalfwordM[15:0]};               // lhu
 | 
			
		||||
        3'b110:  ReadDataExtM = {32'b0, word[31:0]};                    // lwu
 | 
			
		||||
        default: ReadDataExtM = 64'b0;
 | 
			
		||||
      endcase
 | 
			
		||||
    
 | 
			
		||||
      // Memory control
 | 
			
		||||
    
 | 
			
		||||
      // Compute write mask
 | 
			
		||||
      always_comb 
 | 
			
		||||
        if (StoreMisalignedFaultM || StoreAccessFaultM) ByteMaskM = 8'b00000000; // discard Unaligned stores
 | 
			
		||||
        else case(Funct3M)
 | 
			
		||||
          3'b000:  begin ByteMaskM = 8'b00000000; ByteMaskM[DataAdrM[2:0]] = 1; end // sb
 | 
			
		||||
          3'b001:  case (DataAdrM[2:1])
 | 
			
		||||
                    2'b00: ByteMaskM = 8'b00000011;
 | 
			
		||||
                    2'b01: ByteMaskM = 8'b00001100;
 | 
			
		||||
                    2'b10: ByteMaskM = 8'b00110000;
 | 
			
		||||
                    2'b11: ByteMaskM = 8'b11000000;
 | 
			
		||||
                  endcase
 | 
			
		||||
          3'b010:  if (DataAdrM[2]) ByteMaskM = 8'b11110000;
 | 
			
		||||
                   else        ByteMaskM = 8'b00001111;
 | 
			
		||||
          3'b011:  ByteMaskM = 8'b11111111;
 | 
			
		||||
          default: ByteMaskM = 8'b00000000;
 | 
			
		||||
        endcase
 | 
			
		||||
 | 
			
		||||
      // Handle subword writes
 | 
			
		||||
      always_comb 
 | 
			
		||||
      case(Funct3M)
 | 
			
		||||
        3'b000:  WriteDataM = {8{WriteDataFullM[7:0]}};  // sb
 | 
			
		||||
        3'b001:  WriteDataM = {4{WriteDataFullM[15:0]}}; // sh
 | 
			
		||||
        3'b010:  WriteDataM = {2{WriteDataFullM[31:0]}}; // sw
 | 
			
		||||
        3'b011:  WriteDataM = WriteDataFullM;            // sw
 | 
			
		||||
        default: WriteDataM = 64'b0;
 | 
			
		||||
      endcase
 | 
			
		||||
     
 | 
			
		||||
    end else begin // 32-bit
 | 
			
		||||
      // byte mux
 | 
			
		||||
      always_comb
 | 
			
		||||
      case(DataAdrM[1:0])
 | 
			
		||||
        2'b00: bytM = ReadDataM[7:0];
 | 
			
		||||
        2'b01: bytM = ReadDataM[15:8];
 | 
			
		||||
        2'b10: bytM = ReadDataM[23:16];
 | 
			
		||||
        2'b11: bytM = ReadDataM[31:24];
 | 
			
		||||
      endcase
 | 
			
		||||
    
 | 
			
		||||
      // halfword mux
 | 
			
		||||
      always_comb
 | 
			
		||||
      case(DataAdrM[1])
 | 
			
		||||
        1'b0: HalfwordM = ReadDataM[15:0];
 | 
			
		||||
        1'b1: HalfwordM = ReadDataM[31:16];
 | 
			
		||||
      endcase
 | 
			
		||||
 | 
			
		||||
      // sign extension
 | 
			
		||||
      always_comb
 | 
			
		||||
      case(Funct3M) 
 | 
			
		||||
        3'b000:  ReadDataExtM = {{24{bytM[7]}}, bytM};                  // lb
 | 
			
		||||
        3'b001:  ReadDataExtM = {{16{HalfwordM[15]}}, HalfwordM[15:0]}; // lh 
 | 
			
		||||
        3'b010:  ReadDataExtM = ReadDataM;                              // lw
 | 
			
		||||
        3'b100:  ReadDataExtM = {24'b0, bytM[7:0]};                     // lbu
 | 
			
		||||
        3'b101:  ReadDataExtM = {16'b0, HalfwordM[15:0]};               // lhu
 | 
			
		||||
        default: ReadDataExtM = 32'b0;
 | 
			
		||||
      endcase
 | 
			
		||||
    
 | 
			
		||||
      // Memory control
 | 
			
		||||
    
 | 
			
		||||
      // Compute write mask
 | 
			
		||||
      always_comb 
 | 
			
		||||
        if (StoreMisalignedFaultM || StoreAccessFaultM) ByteMaskM = 8'b0000; // discard Unaligned stores
 | 
			
		||||
        else case(Funct3M)
 | 
			
		||||
          3'b000:  begin ByteMaskM = 8'b0000; ByteMaskM[{1'b0,DataAdrM[1:0]}] = 1; end // sb
 | 
			
		||||
          3'b001:  if (DataAdrM[1]) ByteMaskM = 8'b1100;
 | 
			
		||||
                   else         ByteMaskM = 8'b0011;
 | 
			
		||||
          3'b010:  ByteMaskM = 8'b1111;
 | 
			
		||||
          default: ByteMaskM = 8'b0000;
 | 
			
		||||
        endcase
 | 
			
		||||
 | 
			
		||||
      // Handle subword writes
 | 
			
		||||
      always_comb 
 | 
			
		||||
      case(Funct3M)
 | 
			
		||||
        3'b000:  WriteDataM = {4{WriteDataFullM[7:0]}};  // sb
 | 
			
		||||
        3'b001:  WriteDataM = {2{WriteDataFullM[15:0]}}; // sh
 | 
			
		||||
        3'b010:  WriteDataM = WriteDataFullM;            // sw
 | 
			
		||||
        default: WriteDataM = 32'b0;
 | 
			
		||||
      endcase
 | 
			
		||||
    end
 | 
			
		||||
  endgenerate
 | 
			
		||||
 | 
			
		||||
	// Determine if an Unaligned access is taking place
 | 
			
		||||
	always_comb
 | 
			
		||||
		case(Funct3M) 
 | 
			
		||||
		  3'b000:  UnalignedM = 0;                 // lb, sb
 | 
			
		||||
		  3'b001:  UnalignedM = DataAdrM[0];           // lh, sh
 | 
			
		||||
		  3'b010:  UnalignedM = DataAdrM[1] | DataAdrM[0]; // lw, sw, flw, fsw
 | 
			
		||||
		  3'b011:  UnalignedM = |DataAdrM[2:0];        // ld, sd, fld, fsd
 | 
			
		||||
		  3'b100:  UnalignedM = 0;                 // lbu
 | 
			
		||||
		  3'b101:  UnalignedM = DataAdrM[0];           // lhu
 | 
			
		||||
		  3'b110:  UnalignedM = |DataAdrM[1:0];        // lwu
 | 
			
		||||
		  default: UnalignedM = 0;
 | 
			
		||||
		endcase 
 | 
			
		||||
 | 
			
		||||
  // Determine if address is valid
 | 
			
		||||
  assign LoadMisalignedFaultM = UnalignedM & MemRWM[1];
 | 
			
		||||
  assign LoadAccessFaultM = DataAccessFaultM & MemRWM[0];
 | 
			
		||||
  assign StoreMisalignedFaultM = UnalignedM & MemRWM[0];
 | 
			
		||||
  assign StoreAccessFaultM = DataAccessFaultM & MemRWM[0];
 | 
			
		||||
endmodule
 | 
			
		||||
							
								
								
									
										188
									
								
								wally-pipelined/src/subword.sv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										188
									
								
								wally-pipelined/src/subword.sv
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,188 @@
 | 
			
		||||
///////////////////////////////////////////
 | 
			
		||||
// subword.sv
 | 
			
		||||
//
 | 
			
		||||
// Written: David_Harris@hmc.edu 9 January 2021
 | 
			
		||||
// Modified: 
 | 
			
		||||
//
 | 
			
		||||
// Purpose: Masking and muxing for subword accesses
 | 
			
		||||
// 
 | 
			
		||||
// A component of the Wally configurable RISC-V project.
 | 
			
		||||
// 
 | 
			
		||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
 | 
			
		||||
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, 
 | 
			
		||||
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software 
 | 
			
		||||
// is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
 | 
			
		||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 
 | 
			
		||||
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT 
 | 
			
		||||
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
///////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
`include "wally-config.vh"
 | 
			
		||||
 | 
			
		||||
module subword (
 | 
			
		||||
  input  logic [1:0]       MemRWM,
 | 
			
		||||
  input  logic [`XLEN-1:0] ReadDataUnmaskedM,
 | 
			
		||||
  input  logic [`XLEN-1:0] AdrM,
 | 
			
		||||
  input  logic [2:0]       Funct3M,
 | 
			
		||||
  output logic [`XLEN-1:0] ReadDataM,
 | 
			
		||||
  input  logic [`XLEN-1:0] WriteDataM,
 | 
			
		||||
  output logic [`XLEN-1:0] MaskedWriteDataM
 | 
			
		||||
);
 | 
			
		||||
                  
 | 
			
		||||
  logic [7:0]  ByteM; // *** declare locally to generate as either 4 or 8 bits
 | 
			
		||||
  logic [15:0] HalfwordM;
 | 
			
		||||
  logic [`XLEN-1:0] WriteDataSubwordDuplicated;
 | 
			
		||||
  logic [7:0]      ByteMaskM;
 | 
			
		||||
  
 | 
			
		||||
  generate
 | 
			
		||||
    if (`XLEN == 64) begin
 | 
			
		||||
      // ByteMe mux
 | 
			
		||||
      always_comb
 | 
			
		||||
      case(AdrM[2:0])
 | 
			
		||||
        3'b000: ByteM = ReadDataUnmaskedM[7:0];
 | 
			
		||||
        3'b001: ByteM = ReadDataUnmaskedM[15:8];
 | 
			
		||||
        3'b010: ByteM = ReadDataUnmaskedM[23:16];
 | 
			
		||||
        3'b011: ByteM = ReadDataUnmaskedM[31:24];
 | 
			
		||||
        3'b100: ByteM = ReadDataUnmaskedM[39:32];
 | 
			
		||||
        3'b101: ByteM = ReadDataUnmaskedM[47:40];
 | 
			
		||||
        3'b110: ByteM = ReadDataUnmaskedM[55:48];
 | 
			
		||||
        3'b111: ByteM = ReadDataUnmaskedM[63:56];
 | 
			
		||||
      endcase
 | 
			
		||||
    
 | 
			
		||||
      // halfword mux
 | 
			
		||||
      always_comb
 | 
			
		||||
      case(AdrM[2:1])
 | 
			
		||||
        2'b00: HalfwordM = ReadDataUnmaskedM[15:0];
 | 
			
		||||
        2'b01: HalfwordM = ReadDataUnmaskedM[31:16];
 | 
			
		||||
        2'b10: HalfwordM = ReadDataUnmaskedM[47:32];
 | 
			
		||||
        2'b11: HalfwordM = ReadDataUnmaskedM[63:48];
 | 
			
		||||
      endcase
 | 
			
		||||
      
 | 
			
		||||
      logic [31:0] WordM;
 | 
			
		||||
      
 | 
			
		||||
      always_comb
 | 
			
		||||
        case(AdrM[2])
 | 
			
		||||
          1'b0: WordM = ReadDataUnmaskedM[31:0];
 | 
			
		||||
          1'b1: WordM = ReadDataUnmaskedM[63:32];
 | 
			
		||||
        endcase
 | 
			
		||||
 | 
			
		||||
      // sign extension
 | 
			
		||||
      always_comb
 | 
			
		||||
      case(Funct3M) 
 | 
			
		||||
        3'b000:  ReadDataM = {{56{ByteM[7]}}, ByteM};                  // lb
 | 
			
		||||
        3'b001:  ReadDataM = {{48{HalfwordM[15]}}, HalfwordM[15:0]}; // lh 
 | 
			
		||||
        3'b010:  ReadDataM = {{32{WordM[31]}}, WordM[31:0]};           // lw
 | 
			
		||||
        3'b011:  ReadDataM = ReadDataUnmaskedM;                              // ld
 | 
			
		||||
        3'b100:  ReadDataM = {56'b0, ByteM[7:0]};                     // lbu
 | 
			
		||||
        3'b101:  ReadDataM = {48'b0, HalfwordM[15:0]};               // lhu
 | 
			
		||||
        3'b110:  ReadDataM = {32'b0, WordM[31:0]};                    // lwu
 | 
			
		||||
        default: ReadDataM = 64'b0;
 | 
			
		||||
      endcase
 | 
			
		||||
    
 | 
			
		||||
      // Memory control
 | 
			
		||||
    
 | 
			
		||||
      // Compute write mask
 | 
			
		||||
      always_comb 
 | 
			
		||||
        case(Funct3M)
 | 
			
		||||
          3'b000:  begin ByteMaskM = 8'b00000000; ByteMaskM[AdrM[2:0]] = 1; end // sb
 | 
			
		||||
          3'b001:  case (AdrM[2:1])
 | 
			
		||||
                    2'b00: ByteMaskM = 8'b00000011;
 | 
			
		||||
                    2'b01: ByteMaskM = 8'b00001100;
 | 
			
		||||
                    2'b10: ByteMaskM = 8'b00110000;
 | 
			
		||||
                    2'b11: ByteMaskM = 8'b11000000;
 | 
			
		||||
                  endcase
 | 
			
		||||
          3'b010:  if (AdrM[2]) ByteMaskM = 8'b11110000;
 | 
			
		||||
                   else        ByteMaskM = 8'b00001111;
 | 
			
		||||
          3'b011:  ByteMaskM = 8'b11111111;
 | 
			
		||||
          default: ByteMaskM = 8'b00000000;
 | 
			
		||||
        endcase
 | 
			
		||||
 | 
			
		||||
      // Handle subword writes
 | 
			
		||||
      always_comb 
 | 
			
		||||
        case(Funct3M)
 | 
			
		||||
          3'b000:  WriteDataSubwordDuplicated = {8{WriteDataM[7:0]}};  // sb
 | 
			
		||||
          3'b001:  WriteDataSubwordDuplicated = {4{WriteDataM[15:0]}}; // sh
 | 
			
		||||
          3'b010:  WriteDataSubwordDuplicated = {2{WriteDataM[31:0]}}; // sw
 | 
			
		||||
          3'b011:  WriteDataSubwordDuplicated = WriteDataM;            // sw
 | 
			
		||||
          default: WriteDataSubwordDuplicated = 64'b0;
 | 
			
		||||
        endcase
 | 
			
		||||
 | 
			
		||||
      always_comb begin
 | 
			
		||||
        MaskedWriteDataM=ReadDataUnmaskedM;
 | 
			
		||||
        if (ByteMaskM[0]) MaskedWriteDataM[7:0]   = WriteDataSubwordDuplicated[7:0];
 | 
			
		||||
        if (ByteMaskM[1]) MaskedWriteDataM[15:8]  = WriteDataSubwordDuplicated[15:8];
 | 
			
		||||
        if (ByteMaskM[2]) MaskedWriteDataM[23:16] = WriteDataSubwordDuplicated[23:16];
 | 
			
		||||
        if (ByteMaskM[3]) MaskedWriteDataM[31:24] = WriteDataSubwordDuplicated[31:24];
 | 
			
		||||
	      if (ByteMaskM[4]) MaskedWriteDataM[39:32] = WriteDataSubwordDuplicated[39:32];
 | 
			
		||||
	      if (ByteMaskM[5]) MaskedWriteDataM[47:40] = WriteDataSubwordDuplicated[47:40];
 | 
			
		||||
      	if (ByteMaskM[6]) MaskedWriteDataM[55:48] = WriteDataSubwordDuplicated[55:48];
 | 
			
		||||
	      if (ByteMaskM[7]) MaskedWriteDataM[63:56] = WriteDataSubwordDuplicated[63:56];
 | 
			
		||||
      end 
 | 
			
		||||
 | 
			
		||||
    end else begin // 32-bit
 | 
			
		||||
      // byte mux
 | 
			
		||||
      always_comb
 | 
			
		||||
      case(AdrM[1:0])
 | 
			
		||||
        2'b00: ByteM = ReadDataUnmaskedM[7:0];
 | 
			
		||||
        2'b01: ByteM = ReadDataUnmaskedM[15:8];
 | 
			
		||||
        2'b10: ByteM = ReadDataUnmaskedM[23:16];
 | 
			
		||||
        2'b11: ByteM = ReadDataUnmaskedM[31:24];
 | 
			
		||||
      endcase
 | 
			
		||||
    
 | 
			
		||||
      // halfword mux
 | 
			
		||||
      always_comb
 | 
			
		||||
      case(AdrM[1])
 | 
			
		||||
        1'b0: HalfwordM = ReadDataUnmaskedM[15:0];
 | 
			
		||||
        1'b1: HalfwordM = ReadDataUnmaskedM[31:16];
 | 
			
		||||
      endcase
 | 
			
		||||
 | 
			
		||||
      // sign extension
 | 
			
		||||
      always_comb
 | 
			
		||||
      case(Funct3M) 
 | 
			
		||||
        3'b000:  ReadDataM = {{24{ByteM[7]}}, ByteM};                  // lb
 | 
			
		||||
        3'b001:  ReadDataM = {{16{HalfwordM[15]}}, HalfwordM[15:0]}; // lh 
 | 
			
		||||
        3'b010:  ReadDataM = ReadDataUnmaskedM;                              // lw
 | 
			
		||||
        3'b100:  ReadDataM = {24'b0, ByteM[7:0]};                     // lbu
 | 
			
		||||
        3'b101:  ReadDataM = {16'b0, HalfwordM[15:0]};               // lhu
 | 
			
		||||
        default: ReadDataM = 32'b0;
 | 
			
		||||
      endcase
 | 
			
		||||
    
 | 
			
		||||
      // Memory control
 | 
			
		||||
    
 | 
			
		||||
      // Compute write mask
 | 
			
		||||
      always_comb 
 | 
			
		||||
        case(Funct3M)
 | 
			
		||||
          3'b000:  begin ByteMaskM = 8'b0000; ByteMaskM[{1'b0, AdrM[1:0]}] = 1; end // sb
 | 
			
		||||
          3'b001:  if (AdrM[1]) ByteMaskM = 8'b1100;
 | 
			
		||||
                   else         ByteMaskM = 8'b0011;
 | 
			
		||||
          3'b010:  ByteMaskM = 8'b1111;
 | 
			
		||||
          default: ByteMaskM = 8'b0000;
 | 
			
		||||
        endcase
 | 
			
		||||
 | 
			
		||||
      // Handle subword writes
 | 
			
		||||
      always_comb 
 | 
			
		||||
        case(Funct3M)
 | 
			
		||||
          3'b000:  WriteDataSubwordDuplicated = {4{WriteDataM[7:0]}};  // sb
 | 
			
		||||
          3'b001:  WriteDataSubwordDuplicated = {2{WriteDataM[15:0]}}; // sh
 | 
			
		||||
          3'b010:  WriteDataSubwordDuplicated = WriteDataM;            // sw
 | 
			
		||||
          default: WriteDataSubwordDuplicated = 32'b0;
 | 
			
		||||
        endcase
 | 
			
		||||
 | 
			
		||||
      always_comb begin
 | 
			
		||||
        MaskedWriteDataM=ReadDataUnmaskedM;
 | 
			
		||||
        if (ByteMaskM[0]) MaskedWriteDataM[7:0]   = WriteDataSubwordDuplicated[7:0];
 | 
			
		||||
        if (ByteMaskM[1]) MaskedWriteDataM[15:8]  = WriteDataSubwordDuplicated[15:8];
 | 
			
		||||
        if (ByteMaskM[2]) MaskedWriteDataM[23:16] = WriteDataSubwordDuplicated[23:16];
 | 
			
		||||
        if (ByteMaskM[3]) MaskedWriteDataM[31:24] = WriteDataSubwordDuplicated[31:24];
 | 
			
		||||
      end 
 | 
			
		||||
 | 
			
		||||
    end
 | 
			
		||||
  endgenerate
 | 
			
		||||
 | 
			
		||||
endmodule
 | 
			
		||||
@ -30,7 +30,7 @@
 | 
			
		||||
module uart (
 | 
			
		||||
  input  logic            clk, reset, 
 | 
			
		||||
  input  logic [1:0]      MemRWuartM,
 | 
			
		||||
  input  logic [7:0]      ByteMaskM,
 | 
			
		||||
//  input  logic [7:0]      ByteMaskM,
 | 
			
		||||
  input  logic [`XLEN-1:0] AdrM, 
 | 
			
		||||
  input  logic [`XLEN-1:0] MaskedWriteDataM,
 | 
			
		||||
  output logic [`XLEN-1:0] RdUARTM,
 | 
			
		||||
 | 
			
		||||
@ -1,10 +1,11 @@
 | 
			
		||||
///////////////////////////////////////////
 | 
			
		||||
// dmem.sv
 | 
			
		||||
// uncore.sv
 | 
			
		||||
//
 | 
			
		||||
// Written: David_Harris@hmc.edu 9 January 2021
 | 
			
		||||
// Modified: 
 | 
			
		||||
//
 | 
			
		||||
// Purpose: Data memory
 | 
			
		||||
// Purpose: System-on-Chip components outside the core (hart)
 | 
			
		||||
//          Memories, peripherals, external bus control
 | 
			
		||||
// 
 | 
			
		||||
// A component of the Wally configurable RISC-V project.
 | 
			
		||||
// 
 | 
			
		||||
@ -27,26 +28,31 @@
 | 
			
		||||
 | 
			
		||||
// *** need idiom to map onto cache RAM with byte writes
 | 
			
		||||
// *** and use memread signal to reduce power when reads aren't needed
 | 
			
		||||
module dmem (
 | 
			
		||||
module uncore (
 | 
			
		||||
  input  logic            clk, reset,
 | 
			
		||||
  // bus interface
 | 
			
		||||
  input  logic [1:0]      MemRWM,
 | 
			
		||||
  input  logic [7:0]      ByteMaskM,
 | 
			
		||||
  input  logic [`XLEN-1:0] AdrM, WriteDataM,
 | 
			
		||||
  input  logic [2:0]       Funct3M,
 | 
			
		||||
  output logic [`XLEN-1:0] ReadDataM,
 | 
			
		||||
  output logic            DataAccessFaultM,
 | 
			
		||||
  // peripheral pins
 | 
			
		||||
  output logic            TimerIntM, SwIntM,
 | 
			
		||||
  input  logic [31:0]     GPIOPinsIn,
 | 
			
		||||
  output logic [31:0]     GPIOPinsOut, GPIOPinsEn, 
 | 
			
		||||
  input  logic            UARTSin,
 | 
			
		||||
  output logic            UARTSout);
 | 
			
		||||
  output logic            UARTSout
 | 
			
		||||
  );
 | 
			
		||||
  
 | 
			
		||||
  logic [`XLEN-1:0] MaskedWriteDataM;
 | 
			
		||||
  logic [`XLEN-1:0] ReadDataUnmaskedM;
 | 
			
		||||
  logic [`XLEN-1:0] RdTimM, RdCLINTM, RdGPIOM, RdUARTM;
 | 
			
		||||
  logic            TimEnM, CLINTEnM, GPIOEnM, UARTEnM;
 | 
			
		||||
  logic [1:0]      MemRWdtimM, MemRWclintM, MemRWgpioM, MemRWuartM;
 | 
			
		||||
  logic            UARTIntr;// *** will need to tie INTR to an interrupt handler
 | 
			
		||||
 | 
			
		||||
  // Address decoding
 | 
			
		||||
  // *** generalize, use configurable
 | 
			
		||||
  generate
 | 
			
		||||
    if (`XLEN == 64)
 | 
			
		||||
      assign TimEnM = ~(|AdrM[`XLEN-1:32]) & AdrM[31] & ~(|AdrM[30:19]); // 0x000...80000000 - 0x000...8007FFFF
 | 
			
		||||
@ -57,6 +63,7 @@ module dmem (
 | 
			
		||||
  assign GPIOEnM = (AdrM[31:8] == 24'h10012); // 0x10012000-0x100120FF
 | 
			
		||||
  assign UARTEnM = ~(|AdrM[`XLEN-1:29]) & AdrM[28] & ~(|AdrM[27:3]); // 0x10000000-0x10000007
 | 
			
		||||
 | 
			
		||||
  // Enable read or write based on decoded address.
 | 
			
		||||
  assign MemRWdtimM  = MemRWM & {2{TimEnM}};
 | 
			
		||||
  assign MemRWclintM = MemRWM & {2{CLINTEnM}};
 | 
			
		||||
  assign MemRWgpioM  = MemRWM & {2{GPIOEnM}};
 | 
			
		||||
@ -72,37 +79,15 @@ module dmem (
 | 
			
		||||
            .DSRb(1'b1), .DCDb(1'b1), .CTSb(1'b0), .RIb(1'b1), 
 | 
			
		||||
            .RTSb(), .DTRb(), .OUT1b(), .OUT2b(), .*); 
 | 
			
		||||
 | 
			
		||||
  // *** add cache and interface to external memory & other peripherals
 | 
			
		||||
  // *** Interface to off-chip memory would appear as another peripheral
 | 
			
		||||
  
 | 
			
		||||
  // merge reads
 | 
			
		||||
  assign ReadDataM = ({`XLEN{TimEnM}} & RdTimM) | ({`XLEN{CLINTEnM}} & RdCLINTM) | 
 | 
			
		||||
  assign ReadDataUnmaskedM = ({`XLEN{TimEnM}} & RdTimM) | ({`XLEN{CLINTEnM}} & RdCLINTM) | 
 | 
			
		||||
                     ({`XLEN{GPIOEnM}} & RdGPIOM) | ({`XLEN{UARTEnM}} & RdUARTM);
 | 
			
		||||
  assign DataAccessFaultM = ~(|TimEnM | CLINTEnM | GPIOEnM | UARTEnM);
 | 
			
		||||
 | 
			
		||||
  // byte masking
 | 
			
		||||
   // write each byte based on the byte mask
 | 
			
		||||
  generate
 | 
			
		||||
    if (`XLEN==64) begin
 | 
			
		||||
      always_comb begin
 | 
			
		||||
        MaskedWriteDataM=ReadDataM;
 | 
			
		||||
        if (ByteMaskM[0]) MaskedWriteDataM[7:0]   = WriteDataM[7:0];
 | 
			
		||||
        if (ByteMaskM[1]) MaskedWriteDataM[15:8]  = WriteDataM[15:8];
 | 
			
		||||
        if (ByteMaskM[2]) MaskedWriteDataM[23:16] = WriteDataM[23:16];
 | 
			
		||||
        if (ByteMaskM[3]) MaskedWriteDataM[31:24] = WriteDataM[31:24];
 | 
			
		||||
	      if (ByteMaskM[4]) MaskedWriteDataM[39:32] = WriteDataM[39:32];
 | 
			
		||||
	      if (ByteMaskM[5]) MaskedWriteDataM[47:40] = WriteDataM[47:40];
 | 
			
		||||
      	if (ByteMaskM[6]) MaskedWriteDataM[55:48] = WriteDataM[55:48];
 | 
			
		||||
	      if (ByteMaskM[7]) MaskedWriteDataM[63:56] = WriteDataM[63:56];
 | 
			
		||||
      end 
 | 
			
		||||
    end else begin // 32-bit
 | 
			
		||||
      always_comb begin
 | 
			
		||||
        if (ByteMaskM[0]) MaskedWriteDataM[7:0]   = WriteDataM[7:0];
 | 
			
		||||
        if (ByteMaskM[1]) MaskedWriteDataM[15:8]  = WriteDataM[15:8];
 | 
			
		||||
        if (ByteMaskM[2]) MaskedWriteDataM[23:16] = WriteDataM[23:16];
 | 
			
		||||
        if (ByteMaskM[3]) MaskedWriteDataM[31:24] = WriteDataM[31:24];
 | 
			
		||||
      end 
 | 
			
		||||
    end
 | 
			
		||||
  endgenerate
 | 
			
		||||
  assign DataAccessFaultM = ~(TimEnM | CLINTEnM | GPIOEnM | UARTEnM);
 | 
			
		||||
 | 
			
		||||
  // subword accesses: converts ReadDataUnmaskedM to ReadDataM and WriteDataM to MaskedWriteDataM
 | 
			
		||||
  subword subword(.*);
 | 
			
		||||
 
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
@ -30,10 +30,10 @@ module wallypipelinedhart (
 | 
			
		||||
  input  logic            clk, reset,
 | 
			
		||||
  output logic [`XLEN-1:0] PCF,
 | 
			
		||||
  input  logic [31:0]     InstrF,
 | 
			
		||||
  output logic [1:0]      MemRWM,
 | 
			
		||||
  output logic [7:0]      ByteMaskM,
 | 
			
		||||
  output logic [`XLEN-1:0] DataAdrM, WriteDataM,
 | 
			
		||||
  input  logic [`XLEN-1:0] ReadDataM,
 | 
			
		||||
  output logic [1:0]      MemRWdcuoutM, // *** should be removed when EBU enabled
 | 
			
		||||
  output logic [2:0]      Funct3M, // *** remove when EBU enabled
 | 
			
		||||
  output logic [`XLEN-1:0] DataAdrM, WriteDataM, // ***
 | 
			
		||||
  input  logic [`XLEN-1:0] ReadDataM, // ***
 | 
			
		||||
  input  logic            TimerIntM, ExtIntM, SwIntM,
 | 
			
		||||
  input  logic            InstrAccessFaultF,
 | 
			
		||||
  input  logic            DataAccessFaultM,
 | 
			
		||||
@ -62,9 +62,10 @@ module wallypipelinedhart (
 | 
			
		||||
  logic [`XLEN-1:0] PCTargetE;
 | 
			
		||||
  logic [`XLEN-1:0] CSRReadValM;
 | 
			
		||||
  logic [`XLEN-1:0] PrivilegedNextPCM;
 | 
			
		||||
  logic [`XLEN-1:0] ReadDataExtM, WriteDataFullM;
 | 
			
		||||
  logic [1:0] MemRWM;
 | 
			
		||||
  logic InstrValidW;
 | 
			
		||||
  logic InstrMisalignedFaultM;
 | 
			
		||||
  logic DataMisalignedM;
 | 
			
		||||
  logic IllegalBaseInstrFaultD, IllegalIEUInstrFaultD;
 | 
			
		||||
  logic LoadMisalignedFaultM, LoadAccessFaultM;
 | 
			
		||||
  logic StoreMisalignedFaultM, StoreAccessFaultM;
 | 
			
		||||
@ -86,7 +87,7 @@ module wallypipelinedhart (
 | 
			
		||||
  ifu ifu(.*); // instruction fetch unit: PC, branch prediction, instruction cache
 | 
			
		||||
 | 
			
		||||
  ieu ieu(.*); // inteber execution unit: integer register file, datapath and controller
 | 
			
		||||
  dcu dcu(.Funct3M(InstrM[14:12]), .*); // data cache unit
 | 
			
		||||
  dcu dcu(/*.Funct3M(InstrM[14:12]),*/ .*); // data cache unit
 | 
			
		||||
 | 
			
		||||
  ahblite ebu(
 | 
			
		||||
    .IPAdrD(zero), .IReadD(1'b0), .IRData(), .IReady(), 
 | 
			
		||||
 | 
			
		||||
@ -55,7 +55,8 @@ module wallypipelinedsoc (
 | 
			
		||||
  logic [`XLEN-1:0] DataAdrM, WriteDataM;
 | 
			
		||||
  logic [`XLEN-1:0] PCF, ReadDataM;
 | 
			
		||||
  logic [31:0] InstrF;
 | 
			
		||||
  logic [7:0]  ByteMaskM;
 | 
			
		||||
  logic [2:0]  Funct3M;
 | 
			
		||||
  logic [1:0]  MemRWdcuoutM;
 | 
			
		||||
  logic        InstrAccessFaultF, DataAccessFaultM;
 | 
			
		||||
  logic        TimerIntM, SwIntM; // from CLINT
 | 
			
		||||
  logic        ExtIntM = 0; // not yet connected
 | 
			
		||||
@ -64,5 +65,5 @@ module wallypipelinedsoc (
 | 
			
		||||
  wallypipelinedhart hart(.*);
 | 
			
		||||
 | 
			
		||||
  imem imem(.AdrF(PCF[`XLEN-1:1]), .*);
 | 
			
		||||
  dmem dmem(.AdrM(DataAdrM), .*);
 | 
			
		||||
  uncore uncore(.AdrM(DataAdrM), .MemRWM(MemRWdcuoutM), .*);
 | 
			
		||||
endmodule
 | 
			
		||||
@ -263,7 +263,7 @@ string tests32i[] = {
 | 
			
		||||
                dut.hart.ifu.InstrM,  InstrW,
 | 
			
		||||
                InstrDName, InstrEName, InstrMName, InstrWName);
 | 
			
		||||
 | 
			
		||||
  // initialize test
 | 
			
		||||
  // initialize tests
 | 
			
		||||
  initial
 | 
			
		||||
    begin
 | 
			
		||||
      test = 0;
 | 
			
		||||
@ -274,12 +274,12 @@ string tests32i[] = {
 | 
			
		||||
      else meminit = 64'hFEDCBA9876543210;
 | 
			
		||||
      for (i=0; i<=65535; i = i+1) begin
 | 
			
		||||
        //dut.imem.RAM[i] = meminit;
 | 
			
		||||
       // dut.dmem.RAM[i] = meminit;
 | 
			
		||||
       // dut.uncore.RAM[i] = meminit;
 | 
			
		||||
      end
 | 
			
		||||
      // read test vectors into memory
 | 
			
		||||
      memfilename = {"../../imperas-riscv-tests/work/", tests[test], ".elf.memfile"};
 | 
			
		||||
      $readmemh(memfilename, dut.imem.RAM);
 | 
			
		||||
      $readmemh(memfilename, dut.dmem.dtim.RAM);
 | 
			
		||||
      $readmemh(memfilename, dut.uncore.dtim.RAM);
 | 
			
		||||
      reset = 1; # 22; reset = 0;
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
@ -325,13 +325,13 @@ string tests32i[] = {
 | 
			
		||||
        /* verilator lint_off INFINITELOOP */
 | 
			
		||||
        while (signature[i] !== 'bx) begin
 | 
			
		||||
          //$display("signature[%h] = %h", i, signature[i]);
 | 
			
		||||
          if (signature[i] !== dut.dmem.dtim.RAM[testadr+i]) begin
 | 
			
		||||
          if (signature[i] !== dut.uncore.dtim.RAM[testadr+i]) begin
 | 
			
		||||
            if (signature[i+4] !== 'bx || signature[i] !== 32'hFFFFFFFF) begin
 | 
			
		||||
              // report errors unless they are garbage at the end of the sim
 | 
			
		||||
              // kind of hacky test for garbage right now
 | 
			
		||||
              errors = errors+1;
 | 
			
		||||
              $display("  Error on test %s result %d: adr = %h sim = %h, signature = %h", 
 | 
			
		||||
                    tests[test], i, (testadr+i)*`XLEN/8, dut.dmem.dtim.RAM[testadr+i], signature[i]);
 | 
			
		||||
                    tests[test], i, (testadr+i)*`XLEN/8, dut.uncore.dtim.RAM[testadr+i], signature[i]);
 | 
			
		||||
            end
 | 
			
		||||
          end
 | 
			
		||||
          i = i + 1;
 | 
			
		||||
@ -351,7 +351,7 @@ string tests32i[] = {
 | 
			
		||||
        else begin
 | 
			
		||||
          memfilename = {"../../imperas-riscv-tests/work/", tests[test], ".elf.memfile"};
 | 
			
		||||
          $readmemh(memfilename, dut.imem.RAM);
 | 
			
		||||
          $readmemh(memfilename, dut.dmem.dtim.RAM);
 | 
			
		||||
          $readmemh(memfilename, dut.uncore.dtim.RAM);
 | 
			
		||||
          $display("Read memfile %s", memfilename);
 | 
			
		||||
          reset = 1; # 17; reset = 0;
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user