forked from Github_Repos/cvw
Moving data memory to uncore
This commit is contained in:
parent
a94c09cad8
commit
dc2443c55b
@ -57,6 +57,9 @@
|
|||||||
// Address space
|
// Address space
|
||||||
`define RESET_VECTOR 32'h80000000
|
`define RESET_VECTOR 32'h80000000
|
||||||
|
|
||||||
|
// Bus Interface
|
||||||
|
`define AHBW 32
|
||||||
|
|
||||||
// Test modes
|
// Test modes
|
||||||
|
|
||||||
// Tie GPIO outputs back to inputs
|
// Tie GPIO outputs back to inputs
|
||||||
|
@ -63,9 +63,9 @@ add wave -divider
|
|||||||
#add wave -hex /testbench/dut/hart/ifu/PCM
|
#add wave -hex /testbench/dut/hart/ifu/PCM
|
||||||
#add wave -hex /testbench/dut/hart/ifu/InstrM
|
#add wave -hex /testbench/dut/hart/ifu/InstrM
|
||||||
add wave /testbench/InstrMName
|
add wave /testbench/InstrMName
|
||||||
add wave /testbench/dut/dmem/dtim/memwrite
|
add wave /testbench/dut/uncore/dtim/memwrite
|
||||||
add wave -hex /testbench/dut/dmem/AdrM
|
add wave -hex /testbench/dut/uncore/AdrM
|
||||||
add wave -hex /testbench/dut/dmem/WriteDataM
|
add wave -hex /testbench/dut/uncore/WriteDataM
|
||||||
add wave -divider
|
add wave -divider
|
||||||
add wave -hex /testbench/dut/hart/ifu/PCW
|
add wave -hex /testbench/dut/hart/ifu/PCW
|
||||||
add wave /testbench/InstrWName
|
add wave /testbench/InstrWName
|
||||||
|
@ -46,6 +46,7 @@ module controller(
|
|||||||
output logic MemReadE, // for Hazard Unit
|
output logic MemReadE, // for Hazard Unit
|
||||||
// Memory stage control signals
|
// Memory stage control signals
|
||||||
input logic FlushM,
|
input logic FlushM,
|
||||||
|
input logic DataMisalignedM,
|
||||||
output logic [1:0] MemRWM,
|
output logic [1:0] MemRWM,
|
||||||
output logic CSRWriteM, PrivilegedM,
|
output logic CSRWriteM, PrivilegedM,
|
||||||
output logic [2:0] Funct3M,
|
output logic [2:0] Funct3M,
|
||||||
@ -110,7 +111,7 @@ module controller(
|
|||||||
assign {RegWriteD, ImmSrcD, ALUSrcAD, ALUSrcBD, MemRWD,
|
assign {RegWriteD, ImmSrcD, ALUSrcAD, ALUSrcBD, MemRWD,
|
||||||
ResultSrcD, BranchD, ALUOpD, JumpD, TargetSrcD, W64D, CSRWriteD,
|
ResultSrcD, BranchD, ALUOpD, JumpD, TargetSrcD, W64D, CSRWriteD,
|
||||||
PrivilegedD} = ControlsD[18:1] & ~IllegalIEUInstrFaultD;
|
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
|
// ALU Decoding
|
||||||
assign sltD = (Funct3D == 3'b010);
|
assign sltD = (Funct3D == 3'b010);
|
||||||
|
@ -45,10 +45,10 @@ module datapath (
|
|||||||
input logic FlushM,
|
input logic FlushM,
|
||||||
input logic [2:0] Funct3M,
|
input logic [2:0] Funct3M,
|
||||||
input logic [`XLEN-1:0] CSRReadValM,
|
input logic [`XLEN-1:0] CSRReadValM,
|
||||||
input logic [`XLEN-1:0] ReadDataExtM,
|
input logic [`XLEN-1:0] ReadDataM,
|
||||||
input logic RetM, TrapM,
|
input logic RetM, TrapM,
|
||||||
output logic [`XLEN-1:0] SrcAM,
|
output logic [`XLEN-1:0] SrcAM,
|
||||||
output logic [`XLEN-1:0] WriteDataFullM, DataAdrM,
|
output logic [`XLEN-1:0] WriteDataM, DataAdrM,
|
||||||
// Writeback stage signals
|
// Writeback stage signals
|
||||||
input logic FlushW,
|
input logic FlushW,
|
||||||
input logic RegWriteW,
|
input logic RegWriteW,
|
||||||
@ -106,12 +106,12 @@ module datapath (
|
|||||||
floprc #(`XLEN) SrcAMReg(clk, reset, FlushM, SrcAE, SrcAM);
|
floprc #(`XLEN) SrcAMReg(clk, reset, FlushM, SrcAE, SrcAM);
|
||||||
floprc #(`XLEN) ALUResultMReg(clk, reset, FlushM, ALUResultE, ALUResultM);
|
floprc #(`XLEN) ALUResultMReg(clk, reset, FlushM, ALUResultE, ALUResultM);
|
||||||
assign DataAdrM = 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);
|
floprc #(5) RdMEg(clk, reset, FlushM, RdE, RdM);
|
||||||
|
|
||||||
// Writeback stage pipeline register and logic
|
// Writeback stage pipeline register and logic
|
||||||
floprc #(`XLEN) ALUResultWReg(clk, reset, FlushW, ALUResultM, ALUResultW);
|
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 #(`XLEN) CSRValWReg(clk, reset, FlushW, CSRReadValM, CSRValW);
|
||||||
floprc #(5) RdWEg(clk, reset, FlushW, RdM, RdW);
|
floprc #(5) RdWEg(clk, reset, FlushW, RdM, RdW);
|
||||||
|
|
||||||
|
@ -29,19 +29,40 @@
|
|||||||
|
|
||||||
module dcu (
|
module dcu (
|
||||||
input logic [1:0] MemRWM,
|
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 [`XLEN-1:0] DataAdrM,
|
||||||
input logic [2:0] Funct3M,
|
input logic [2:0] Funct3M,
|
||||||
output logic [`XLEN-1:0] ReadDataExtM,
|
/* output logic [`XLEN-1:0] ReadDataM,
|
||||||
input logic [`XLEN-1:0] WriteDataFullM,
|
input logic [`XLEN-1:0] WriteDataM, */
|
||||||
output logic [`XLEN-1:0] WriteDataM,
|
// faults
|
||||||
output logic [7:0] ByteMaskM,
|
|
||||||
input logic DataAccessFaultM,
|
input logic DataAccessFaultM,
|
||||||
output logic LoadMisalignedFaultM, LoadAccessFaultM,
|
output logic LoadMisalignedFaultM, LoadAccessFaultM,
|
||||||
output logic StoreMisalignedFaultM, StoreAccessFaultM
|
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
|
endmodule
|
||||||
|
|
||||||
|
@ -28,9 +28,9 @@
|
|||||||
module dtim (
|
module dtim (
|
||||||
input logic clk,
|
input logic clk,
|
||||||
input logic [1:0] MemRWdtimM,
|
input logic [1:0] MemRWdtimM,
|
||||||
input logic [7:0] ByteMaskM,
|
// input logic [7:0] ByteMaskM,
|
||||||
input logic [18:0] AdrM,
|
input logic [18:0] AdrM,
|
||||||
input logic [`XLEN-1:0] WriteDataM,
|
input logic [`XLEN-1:0] MaskedWriteDataM,
|
||||||
output logic [`XLEN-1:0] RdTimM);
|
output logic [`XLEN-1:0] RdTimM);
|
||||||
|
|
||||||
logic [`XLEN-1:0] RAM[0:65535];
|
logic [`XLEN-1:0] RAM[0:65535];
|
||||||
@ -54,7 +54,7 @@ module dtim (
|
|||||||
// UInstantiate a byte-writable memory here if possible
|
// UInstantiate a byte-writable memory here if possible
|
||||||
// and drop tihs masking logic. Otherwise, use the masking
|
// and drop tihs masking logic. Otherwise, use the masking
|
||||||
// from dmem
|
// from dmem
|
||||||
generate
|
/*generate
|
||||||
|
|
||||||
if (`XLEN==64) begin
|
if (`XLEN==64) begin
|
||||||
always_comb begin
|
always_comb begin
|
||||||
@ -81,6 +81,15 @@ module dtim (
|
|||||||
always_ff @(posedge clk)
|
always_ff @(posedge clk)
|
||||||
if (memwrite) RAM[AdrM[17:2]] <= write;
|
if (memwrite) RAM[AdrM[17:2]] <= write;
|
||||||
end
|
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
|
endgenerate
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
@ -28,8 +28,9 @@
|
|||||||
module ieu (
|
module ieu (
|
||||||
input logic clk, reset,
|
input logic clk, reset,
|
||||||
output logic [1:0] MemRWM,
|
output logic [1:0] MemRWM,
|
||||||
output logic [`XLEN-1:0] DataAdrM, WriteDataFullM,
|
output logic [`XLEN-1:0] DataAdrM, WriteDataM,
|
||||||
input logic [`XLEN-1:0] ReadDataExtM,
|
input logic [`XLEN-1:0] ReadDataM,
|
||||||
|
input logic DataMisalignedM,
|
||||||
input logic DataAccessFaultM,
|
input logic DataAccessFaultM,
|
||||||
input logic [1:0] ForwardAE, ForwardBE,
|
input logic [1:0] ForwardAE, ForwardBE,
|
||||||
input logic StallD, FlushD, FlushE, FlushM, FlushW,
|
input logic StallD, FlushD, FlushE, FlushM, FlushW,
|
||||||
@ -39,6 +40,7 @@ module ieu (
|
|||||||
output logic RegWriteW,
|
output logic RegWriteW,
|
||||||
output logic CSRWriteM, PrivilegedM,
|
output logic CSRWriteM, PrivilegedM,
|
||||||
output logic CSRWritePendingDEM,
|
output logic CSRWritePendingDEM,
|
||||||
|
output logic [2:0] Funct3M,
|
||||||
output logic [`XLEN-1:0] SrcAM,
|
output logic [`XLEN-1:0] SrcAM,
|
||||||
output logic [`XLEN-1:0] PCTargetE,
|
output logic [`XLEN-1:0] PCTargetE,
|
||||||
input logic [31:0] InstrD,
|
input logic [31:0] InstrD,
|
||||||
@ -56,7 +58,6 @@ module ieu (
|
|||||||
logic [2:0] FlagsE;
|
logic [2:0] FlagsE;
|
||||||
logic [4:0] ALUControlE;
|
logic [4:0] ALUControlE;
|
||||||
logic ALUSrcAE, ALUSrcBE;
|
logic ALUSrcAE, ALUSrcBE;
|
||||||
logic [2:0] Funct3M;
|
|
||||||
logic [1:0] ResultSrcW;
|
logic [1:0] ResultSrcW;
|
||||||
|
|
||||||
logic TargetSrcE;
|
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 (
|
module uart (
|
||||||
input logic clk, reset,
|
input logic clk, reset,
|
||||||
input logic [1:0] MemRWuartM,
|
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] AdrM,
|
||||||
input logic [`XLEN-1:0] MaskedWriteDataM,
|
input logic [`XLEN-1:0] MaskedWriteDataM,
|
||||||
output logic [`XLEN-1:0] RdUARTM,
|
output logic [`XLEN-1:0] RdUARTM,
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
///////////////////////////////////////////
|
///////////////////////////////////////////
|
||||||
// dmem.sv
|
// uncore.sv
|
||||||
//
|
//
|
||||||
// Written: David_Harris@hmc.edu 9 January 2021
|
// Written: David_Harris@hmc.edu 9 January 2021
|
||||||
// Modified:
|
// 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.
|
// A component of the Wally configurable RISC-V project.
|
||||||
//
|
//
|
||||||
@ -27,26 +28,31 @@
|
|||||||
|
|
||||||
// *** need idiom to map onto cache RAM with byte writes
|
// *** need idiom to map onto cache RAM with byte writes
|
||||||
// *** and use memread signal to reduce power when reads aren't needed
|
// *** and use memread signal to reduce power when reads aren't needed
|
||||||
module dmem (
|
module uncore (
|
||||||
input logic clk, reset,
|
input logic clk, reset,
|
||||||
|
// bus interface
|
||||||
input logic [1:0] MemRWM,
|
input logic [1:0] MemRWM,
|
||||||
input logic [7:0] ByteMaskM,
|
|
||||||
input logic [`XLEN-1:0] AdrM, WriteDataM,
|
input logic [`XLEN-1:0] AdrM, WriteDataM,
|
||||||
|
input logic [2:0] Funct3M,
|
||||||
output logic [`XLEN-1:0] ReadDataM,
|
output logic [`XLEN-1:0] ReadDataM,
|
||||||
output logic DataAccessFaultM,
|
output logic DataAccessFaultM,
|
||||||
|
// peripheral pins
|
||||||
output logic TimerIntM, SwIntM,
|
output logic TimerIntM, SwIntM,
|
||||||
input logic [31:0] GPIOPinsIn,
|
input logic [31:0] GPIOPinsIn,
|
||||||
output logic [31:0] GPIOPinsOut, GPIOPinsEn,
|
output logic [31:0] GPIOPinsOut, GPIOPinsEn,
|
||||||
input logic UARTSin,
|
input logic UARTSin,
|
||||||
output logic UARTSout);
|
output logic UARTSout
|
||||||
|
);
|
||||||
|
|
||||||
logic [`XLEN-1:0] MaskedWriteDataM;
|
logic [`XLEN-1:0] MaskedWriteDataM;
|
||||||
|
logic [`XLEN-1:0] ReadDataUnmaskedM;
|
||||||
logic [`XLEN-1:0] RdTimM, RdCLINTM, RdGPIOM, RdUARTM;
|
logic [`XLEN-1:0] RdTimM, RdCLINTM, RdGPIOM, RdUARTM;
|
||||||
logic TimEnM, CLINTEnM, GPIOEnM, UARTEnM;
|
logic TimEnM, CLINTEnM, GPIOEnM, UARTEnM;
|
||||||
logic [1:0] MemRWdtimM, MemRWclintM, MemRWgpioM, MemRWuartM;
|
logic [1:0] MemRWdtimM, MemRWclintM, MemRWgpioM, MemRWuartM;
|
||||||
logic UARTIntr;// *** will need to tie INTR to an interrupt handler
|
logic UARTIntr;// *** will need to tie INTR to an interrupt handler
|
||||||
|
|
||||||
// Address decoding
|
// Address decoding
|
||||||
|
// *** generalize, use configurable
|
||||||
generate
|
generate
|
||||||
if (`XLEN == 64)
|
if (`XLEN == 64)
|
||||||
assign TimEnM = ~(|AdrM[`XLEN-1:32]) & AdrM[31] & ~(|AdrM[30:19]); // 0x000...80000000 - 0x000...8007FFFF
|
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 GPIOEnM = (AdrM[31:8] == 24'h10012); // 0x10012000-0x100120FF
|
||||||
assign UARTEnM = ~(|AdrM[`XLEN-1:29]) & AdrM[28] & ~(|AdrM[27:3]); // 0x10000000-0x10000007
|
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 MemRWdtimM = MemRWM & {2{TimEnM}};
|
||||||
assign MemRWclintM = MemRWM & {2{CLINTEnM}};
|
assign MemRWclintM = MemRWM & {2{CLINTEnM}};
|
||||||
assign MemRWgpioM = MemRWM & {2{GPIOEnM}};
|
assign MemRWgpioM = MemRWM & {2{GPIOEnM}};
|
||||||
@ -72,37 +79,15 @@ module dmem (
|
|||||||
.DSRb(1'b1), .DCDb(1'b1), .CTSb(1'b0), .RIb(1'b1),
|
.DSRb(1'b1), .DCDb(1'b1), .CTSb(1'b0), .RIb(1'b1),
|
||||||
.RTSb(), .DTRb(), .OUT1b(), .OUT2b(), .*);
|
.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
|
// merge reads
|
||||||
assign ReadDataM = ({`XLEN{TimEnM}} & RdTimM) | ({`XLEN{CLINTEnM}} & RdCLINTM) |
|
assign ReadDataUnmaskedM = ({`XLEN{TimEnM}} & RdTimM) | ({`XLEN{CLINTEnM}} & RdCLINTM) |
|
||||||
({`XLEN{GPIOEnM}} & RdGPIOM) | ({`XLEN{UARTEnM}} & RdUARTM);
|
({`XLEN{GPIOEnM}} & RdGPIOM) | ({`XLEN{UARTEnM}} & RdUARTM);
|
||||||
assign DataAccessFaultM = ~(|TimEnM | CLINTEnM | GPIOEnM | UARTEnM);
|
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
|
|
||||||
|
|
||||||
|
// subword accesses: converts ReadDataUnmaskedM to ReadDataM and WriteDataM to MaskedWriteDataM
|
||||||
|
subword subword(.*);
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
@ -30,10 +30,10 @@ module wallypipelinedhart (
|
|||||||
input logic clk, reset,
|
input logic clk, reset,
|
||||||
output logic [`XLEN-1:0] PCF,
|
output logic [`XLEN-1:0] PCF,
|
||||||
input logic [31:0] InstrF,
|
input logic [31:0] InstrF,
|
||||||
output logic [1:0] MemRWM,
|
output logic [1:0] MemRWdcuoutM, // *** should be removed when EBU enabled
|
||||||
output logic [7:0] ByteMaskM,
|
output logic [2:0] Funct3M, // *** remove when EBU enabled
|
||||||
output logic [`XLEN-1:0] DataAdrM, WriteDataM,
|
output logic [`XLEN-1:0] DataAdrM, WriteDataM, // ***
|
||||||
input logic [`XLEN-1:0] ReadDataM,
|
input logic [`XLEN-1:0] ReadDataM, // ***
|
||||||
input logic TimerIntM, ExtIntM, SwIntM,
|
input logic TimerIntM, ExtIntM, SwIntM,
|
||||||
input logic InstrAccessFaultF,
|
input logic InstrAccessFaultF,
|
||||||
input logic DataAccessFaultM,
|
input logic DataAccessFaultM,
|
||||||
@ -62,9 +62,10 @@ module wallypipelinedhart (
|
|||||||
logic [`XLEN-1:0] PCTargetE;
|
logic [`XLEN-1:0] PCTargetE;
|
||||||
logic [`XLEN-1:0] CSRReadValM;
|
logic [`XLEN-1:0] CSRReadValM;
|
||||||
logic [`XLEN-1:0] PrivilegedNextPCM;
|
logic [`XLEN-1:0] PrivilegedNextPCM;
|
||||||
logic [`XLEN-1:0] ReadDataExtM, WriteDataFullM;
|
logic [1:0] MemRWM;
|
||||||
logic InstrValidW;
|
logic InstrValidW;
|
||||||
logic InstrMisalignedFaultM;
|
logic InstrMisalignedFaultM;
|
||||||
|
logic DataMisalignedM;
|
||||||
logic IllegalBaseInstrFaultD, IllegalIEUInstrFaultD;
|
logic IllegalBaseInstrFaultD, IllegalIEUInstrFaultD;
|
||||||
logic LoadMisalignedFaultM, LoadAccessFaultM;
|
logic LoadMisalignedFaultM, LoadAccessFaultM;
|
||||||
logic StoreMisalignedFaultM, StoreAccessFaultM;
|
logic StoreMisalignedFaultM, StoreAccessFaultM;
|
||||||
@ -86,7 +87,7 @@ module wallypipelinedhart (
|
|||||||
ifu ifu(.*); // instruction fetch unit: PC, branch prediction, instruction cache
|
ifu ifu(.*); // instruction fetch unit: PC, branch prediction, instruction cache
|
||||||
|
|
||||||
ieu ieu(.*); // inteber execution unit: integer register file, datapath and controller
|
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(
|
ahblite ebu(
|
||||||
.IPAdrD(zero), .IReadD(1'b0), .IRData(), .IReady(),
|
.IPAdrD(zero), .IReadD(1'b0), .IRData(), .IReady(),
|
||||||
|
@ -55,7 +55,8 @@ module wallypipelinedsoc (
|
|||||||
logic [`XLEN-1:0] DataAdrM, WriteDataM;
|
logic [`XLEN-1:0] DataAdrM, WriteDataM;
|
||||||
logic [`XLEN-1:0] PCF, ReadDataM;
|
logic [`XLEN-1:0] PCF, ReadDataM;
|
||||||
logic [31:0] InstrF;
|
logic [31:0] InstrF;
|
||||||
logic [7:0] ByteMaskM;
|
logic [2:0] Funct3M;
|
||||||
|
logic [1:0] MemRWdcuoutM;
|
||||||
logic InstrAccessFaultF, DataAccessFaultM;
|
logic InstrAccessFaultF, DataAccessFaultM;
|
||||||
logic TimerIntM, SwIntM; // from CLINT
|
logic TimerIntM, SwIntM; // from CLINT
|
||||||
logic ExtIntM = 0; // not yet connected
|
logic ExtIntM = 0; // not yet connected
|
||||||
@ -64,5 +65,5 @@ module wallypipelinedsoc (
|
|||||||
wallypipelinedhart hart(.*);
|
wallypipelinedhart hart(.*);
|
||||||
|
|
||||||
imem imem(.AdrF(PCF[`XLEN-1:1]), .*);
|
imem imem(.AdrF(PCF[`XLEN-1:1]), .*);
|
||||||
dmem dmem(.AdrM(DataAdrM), .*);
|
uncore uncore(.AdrM(DataAdrM), .MemRWM(MemRWdcuoutM), .*);
|
||||||
endmodule
|
endmodule
|
@ -263,7 +263,7 @@ string tests32i[] = {
|
|||||||
dut.hart.ifu.InstrM, InstrW,
|
dut.hart.ifu.InstrM, InstrW,
|
||||||
InstrDName, InstrEName, InstrMName, InstrWName);
|
InstrDName, InstrEName, InstrMName, InstrWName);
|
||||||
|
|
||||||
// initialize test
|
// initialize tests
|
||||||
initial
|
initial
|
||||||
begin
|
begin
|
||||||
test = 0;
|
test = 0;
|
||||||
@ -274,12 +274,12 @@ string tests32i[] = {
|
|||||||
else meminit = 64'hFEDCBA9876543210;
|
else meminit = 64'hFEDCBA9876543210;
|
||||||
for (i=0; i<=65535; i = i+1) begin
|
for (i=0; i<=65535; i = i+1) begin
|
||||||
//dut.imem.RAM[i] = meminit;
|
//dut.imem.RAM[i] = meminit;
|
||||||
// dut.dmem.RAM[i] = meminit;
|
// dut.uncore.RAM[i] = meminit;
|
||||||
end
|
end
|
||||||
// read test vectors into memory
|
// read test vectors into memory
|
||||||
memfilename = {"../../imperas-riscv-tests/work/", tests[test], ".elf.memfile"};
|
memfilename = {"../../imperas-riscv-tests/work/", tests[test], ".elf.memfile"};
|
||||||
$readmemh(memfilename, dut.imem.RAM);
|
$readmemh(memfilename, dut.imem.RAM);
|
||||||
$readmemh(memfilename, dut.dmem.dtim.RAM);
|
$readmemh(memfilename, dut.uncore.dtim.RAM);
|
||||||
reset = 1; # 22; reset = 0;
|
reset = 1; # 22; reset = 0;
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -325,13 +325,13 @@ string tests32i[] = {
|
|||||||
/* verilator lint_off INFINITELOOP */
|
/* verilator lint_off INFINITELOOP */
|
||||||
while (signature[i] !== 'bx) begin
|
while (signature[i] !== 'bx) begin
|
||||||
//$display("signature[%h] = %h", i, signature[i]);
|
//$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
|
if (signature[i+4] !== 'bx || signature[i] !== 32'hFFFFFFFF) begin
|
||||||
// report errors unless they are garbage at the end of the sim
|
// report errors unless they are garbage at the end of the sim
|
||||||
// kind of hacky test for garbage right now
|
// kind of hacky test for garbage right now
|
||||||
errors = errors+1;
|
errors = errors+1;
|
||||||
$display(" Error on test %s result %d: adr = %h sim = %h, signature = %h",
|
$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
|
||||||
end
|
end
|
||||||
i = i + 1;
|
i = i + 1;
|
||||||
@ -351,7 +351,7 @@ string tests32i[] = {
|
|||||||
else begin
|
else begin
|
||||||
memfilename = {"../../imperas-riscv-tests/work/", tests[test], ".elf.memfile"};
|
memfilename = {"../../imperas-riscv-tests/work/", tests[test], ".elf.memfile"};
|
||||||
$readmemh(memfilename, dut.imem.RAM);
|
$readmemh(memfilename, dut.imem.RAM);
|
||||||
$readmemh(memfilename, dut.dmem.dtim.RAM);
|
$readmemh(memfilename, dut.uncore.dtim.RAM);
|
||||||
$display("Read memfile %s", memfilename);
|
$display("Read memfile %s", memfilename);
|
||||||
reset = 1; # 17; reset = 0;
|
reset = 1; # 17; reset = 0;
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user