forked from Github_Repos/cvw
		
	Merge branch 'cache' into main
This commit is contained in:
		
						commit
						108f18e580
					
				@ -45,13 +45,15 @@ add wave /testbench_busybear/reset
 | 
				
			|||||||
add wave -divider
 | 
					add wave -divider
 | 
				
			||||||
add wave -hex /testbench_busybear/PCtext
 | 
					add wave -hex /testbench_busybear/PCtext
 | 
				
			||||||
add wave -hex /testbench_busybear/pcExpected
 | 
					add wave -hex /testbench_busybear/pcExpected
 | 
				
			||||||
add wave -hex /testbench_busybear/dut/hart/ifu/PCF
 | 
					add wave -hex /testbench_busybear/dut/hart/ifu/PCD
 | 
				
			||||||
add wave -hex /testbench_busybear/dut/hart/ifu/InstrF
 | 
					add wave -hex /testbench_busybear/dut/hart/ifu/InstrD
 | 
				
			||||||
add wave -hex /testbench_busybear/dut/hart/ifu/StallD
 | 
					add wave -hex /testbench_busybear/dut/hart/ifu/StallD
 | 
				
			||||||
add wave -hex /testbench_busybear/dut/hart/ifu/FlushD
 | 
					add wave -hex /testbench_busybear/dut/hart/ifu/FlushD
 | 
				
			||||||
 | 
					add wave -hex /testbench_busybear/dut/hart/ifu/StallE
 | 
				
			||||||
 | 
					add wave -hex /testbench_busybear/dut/hart/ifu/FlushE
 | 
				
			||||||
add wave -hex /testbench_busybear/dut/hart/ifu/InstrRawD
 | 
					add wave -hex /testbench_busybear/dut/hart/ifu/InstrRawD
 | 
				
			||||||
add wave /testbench_busybear/CheckInstrF
 | 
					add wave /testbench_busybear/CheckInstrD
 | 
				
			||||||
add wave /testbench_busybear/lastCheckInstrF
 | 
					add wave /testbench_busybear/lastCheckInstrD
 | 
				
			||||||
add wave /testbench_busybear/speculative
 | 
					add wave /testbench_busybear/speculative
 | 
				
			||||||
add wave /testbench_busybear/lastPC2
 | 
					add wave /testbench_busybear/lastPC2
 | 
				
			||||||
add wave -divider
 | 
					add wave -divider
 | 
				
			||||||
 | 
				
			|||||||
@ -42,7 +42,7 @@ vsim workopt
 | 
				
			|||||||
view wave
 | 
					view wave
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- display input and output signals as hexidecimal values
 | 
					-- display input and output signals as hexidecimal values
 | 
				
			||||||
do ./wave-dos/default-waves.do
 | 
					do ./wave-dos/ahb-waves.do
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- Set Wave Output Items 
 | 
					-- Set Wave Output Items 
 | 
				
			||||||
TreeUpdate [SetDefaultTree]
 | 
					TreeUpdate [SetDefaultTree]
 | 
				
			||||||
 | 
				
			|||||||
@ -14,14 +14,21 @@ add wave /testbench/dut/hart/FlushD
 | 
				
			|||||||
add wave /testbench/dut/hart/FlushE
 | 
					add wave /testbench/dut/hart/FlushE
 | 
				
			||||||
add wave /testbench/dut/hart/FlushM
 | 
					add wave /testbench/dut/hart/FlushM
 | 
				
			||||||
add wave /testbench/dut/hart/FlushW
 | 
					add wave /testbench/dut/hart/FlushW
 | 
				
			||||||
add wave -divider
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					add wave -divider
 | 
				
			||||||
add wave -hex /testbench/dut/hart/ifu/PCF
 | 
					add wave -hex /testbench/dut/hart/ifu/PCF
 | 
				
			||||||
add wave -hex /testbench/dut/hart/ifu/InstrF
 | 
					 | 
				
			||||||
add wave /testbench/InstrFName
 | 
					 | 
				
			||||||
add wave -hex /testbench/dut/hart/ifu/PCD
 | 
					add wave -hex /testbench/dut/hart/ifu/PCD
 | 
				
			||||||
add wave -hex /testbench/dut/hart/ifu/InstrD
 | 
					add wave -hex /testbench/dut/hart/ifu/InstrD
 | 
				
			||||||
 | 
					
 | 
				
			||||||
add wave /testbench/InstrDName
 | 
					add wave /testbench/InstrDName
 | 
				
			||||||
 | 
					add wave -hex /testbench/dut/hart/ifu/ic/InstrRawD
 | 
				
			||||||
 | 
					add wave -hex /testbench/dut/hart/ifu/ic/AlignedInstrD
 | 
				
			||||||
 | 
					add wave -divider
 | 
				
			||||||
 | 
					add wave -hex /testbench/dut/hart/ifu/ic/InstrPAdrF
 | 
				
			||||||
 | 
					add wave /testbench/dut/hart/ifu/ic/DelayF
 | 
				
			||||||
 | 
					add wave /testbench/dut/hart/ifu/ic/DelaySideF
 | 
				
			||||||
 | 
					add wave /testbench/dut/hart/ifu/ic/DelayD
 | 
				
			||||||
 | 
					add wave -hex /testbench/dut/hart/ifu/ic/MisalignedHalfInstrD
 | 
				
			||||||
add wave -divider
 | 
					add wave -divider
 | 
				
			||||||
 | 
					
 | 
				
			||||||
add wave -hex /testbench/dut/hart/ifu/PCE
 | 
					add wave -hex /testbench/dut/hart/ifu/PCE
 | 
				
			||||||
@ -55,8 +62,11 @@ add wave -hex /testbench/dut/hart/ebu/CaptureDataM
 | 
				
			|||||||
add wave -hex /testbench/dut/hart/ebu/InstrStall
 | 
					add wave -hex /testbench/dut/hart/ebu/InstrStall
 | 
				
			||||||
add wave -divider
 | 
					add wave -divider
 | 
				
			||||||
 | 
					
 | 
				
			||||||
add wave -hex /testbench/PCW
 | 
					add wave -hex /testbench/dut/uncore/dtim/*
 | 
				
			||||||
add wave -hex /testbench/InstrW
 | 
					add wave -divider
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					add wave -hex /testbench/dut/hart/ifu/PCW
 | 
				
			||||||
 | 
					add wave -hex /testbench/dut/hart/ifu/InstrW
 | 
				
			||||||
add wave /testbench/InstrWName
 | 
					add wave /testbench/InstrWName
 | 
				
			||||||
add wave /testbench/dut/hart/ieu/dp/RegWriteW
 | 
					add wave /testbench/dut/hart/ieu/dp/RegWriteW
 | 
				
			||||||
add wave -hex /testbench/dut/hart/ebu/ReadDataW
 | 
					add wave -hex /testbench/dut/hart/ebu/ReadDataW
 | 
				
			||||||
@ -67,4 +77,4 @@ add wave -divider
 | 
				
			|||||||
add wave -hex /testbench/dut/uncore/dtim/*
 | 
					add wave -hex /testbench/dut/uncore/dtim/*
 | 
				
			||||||
add wave -divider
 | 
					add wave -divider
 | 
				
			||||||
 | 
					
 | 
				
			||||||
add wave -hex -r /testbench/*
 | 
					add wave -hex -r /testbench/*
 | 
				
			||||||
 | 
				
			|||||||
@ -19,11 +19,15 @@ add wave /testbench/dut/hart/FlushW
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
add wave -divider
 | 
					add wave -divider
 | 
				
			||||||
add wave -hex /testbench/dut/hart/ifu/PCF
 | 
					add wave -hex /testbench/dut/hart/ifu/PCF
 | 
				
			||||||
add wave -hex /testbench/dut/hart/ifu/InstrF
 | 
					 | 
				
			||||||
add wave /testbench/InstrFName
 | 
					 | 
				
			||||||
add wave -hex /testbench/dut/hart/ifu/PCD
 | 
					add wave -hex /testbench/dut/hart/ifu/PCD
 | 
				
			||||||
add wave -hex /testbench/dut/hart/ifu/InstrD
 | 
					add wave -hex /testbench/dut/hart/ifu/InstrD
 | 
				
			||||||
add wave /testbench/InstrDName
 | 
					add wave /testbench/InstrDName
 | 
				
			||||||
 | 
					add wave -hex /testbench/dut/hart/ifu/ic/InstrRawD
 | 
				
			||||||
 | 
					add wave -hex /testbench/dut/hart/ifu/ic/AlignedInstrD
 | 
				
			||||||
 | 
					add wave /testbench/dut/hart/ifu/ic/DelayF
 | 
				
			||||||
 | 
					add wave /testbench/dut/hart/ifu/ic/DelaySideF
 | 
				
			||||||
 | 
					add wave /testbench/dut/hart/ifu/ic/DelayD
 | 
				
			||||||
 | 
					add wave -hex /testbench/dut/hart/ifu/ic/MisalignedHalfInstrD
 | 
				
			||||||
add wave -divider
 | 
					add wave -divider
 | 
				
			||||||
add wave -hex /testbench/dut/hart/ifu/PCE
 | 
					add wave -hex /testbench/dut/hart/ifu/PCE
 | 
				
			||||||
add wave -hex /testbench/dut/hart/ifu/InstrE
 | 
					add wave -hex /testbench/dut/hart/ifu/InstrE
 | 
				
			||||||
@ -48,4 +52,4 @@ add wave -hex /testbench/dut/hart/ieu/dp/ResultW
 | 
				
			|||||||
add wave -hex /testbench/dut/hart/ieu/dp/RdW
 | 
					add wave -hex /testbench/dut/hart/ieu/dp/RdW
 | 
				
			||||||
add wave -divider
 | 
					add wave -divider
 | 
				
			||||||
#add ww
 | 
					#add ww
 | 
				
			||||||
add wave -hex -r /testbench/*
 | 
					add wave -hex -r /testbench/*
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										93
									
								
								wally-pipelined/src/cache/dmapped.sv
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								wally-pipelined/src/cache/dmapped.sv
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,93 @@
 | 
				
			|||||||
 | 
					///////////////////////////////////////////
 | 
				
			||||||
 | 
					// dmapped.sv
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Written: jaallen@g.hmc.edu 2021-03-23
 | 
				
			||||||
 | 
					// Modified: 
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Purpose: An implementation of a direct-mapped cache memory
 | 
				
			||||||
 | 
					// This cache is read-only, so "write"s to the memory are loading new data
 | 
				
			||||||
 | 
					// 
 | 
				
			||||||
 | 
					// 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 rodirectmappedmem #(parameter LINESIZE = 256, parameter NUMLINES = 512, parameter WORDSIZE = `XLEN) (
 | 
				
			||||||
 | 
					    // Pipeline stuff
 | 
				
			||||||
 | 
					    input  logic clk,
 | 
				
			||||||
 | 
					    input  logic reset,
 | 
				
			||||||
 | 
					    // If flush is high, invalidate the entire cache
 | 
				
			||||||
 | 
					    input  logic flush,
 | 
				
			||||||
 | 
					    // Select which address to read (broken for efficiency's sake)
 | 
				
			||||||
 | 
					    input  logic [`XLEN-1:12]   ReadUpperPAdr,
 | 
				
			||||||
 | 
					    input  logic [11:0]         ReadLowerAdr,
 | 
				
			||||||
 | 
					    // Write new data to the cache
 | 
				
			||||||
 | 
					    input  logic                WriteEnable,
 | 
				
			||||||
 | 
					    input  logic [LINESIZE-1:0] WriteLine,
 | 
				
			||||||
 | 
					    input  logic [`XLEN-1:0]    WritePAdr,
 | 
				
			||||||
 | 
					    // Output the word, as well as if it is valid
 | 
				
			||||||
 | 
					    output logic [WORDSIZE-1:0] DataWord,
 | 
				
			||||||
 | 
					    output logic                DataValid
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    localparam integer SETWIDTH    = $clog2(NUMLINES);
 | 
				
			||||||
 | 
					    localparam integer OFFSETWIDTH = $clog2(LINESIZE/8);
 | 
				
			||||||
 | 
					    localparam integer TAGWIDTH    = `XLEN-SETWIDTH-OFFSETWIDTH;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    logic [NUMLINES-1:0][WORDSIZE-1:0]  LineOutputs;
 | 
				
			||||||
 | 
					    logic [NUMLINES-1:0]                ValidOutputs;
 | 
				
			||||||
 | 
					    logic [NUMLINES-1:0][TAGWIDTH-1:0]  TagOutputs;
 | 
				
			||||||
 | 
					    logic [OFFSETWIDTH-1:0]             WordSelect;
 | 
				
			||||||
 | 
					    logic [`XLEN-1:0]                   ReadPAdr;
 | 
				
			||||||
 | 
					    logic [SETWIDTH-1:0]                ReadSet, WriteSet;
 | 
				
			||||||
 | 
					    logic [TAGWIDTH-1:0]                ReadTag, WriteTag;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Swizzle bits to get the offset, set, and tag out of the read and write addresses
 | 
				
			||||||
 | 
					    always_comb begin
 | 
				
			||||||
 | 
					        // Read address
 | 
				
			||||||
 | 
					        assign WordSelect = ReadLowerAdr[OFFSETWIDTH-1:0];
 | 
				
			||||||
 | 
					        assign ReadPAdr = {ReadUpperPAdr, ReadLowerAdr};
 | 
				
			||||||
 | 
					        assign ReadSet = ReadPAdr[SETWIDTH+OFFSETWIDTH-1:OFFSETWIDTH];
 | 
				
			||||||
 | 
					        assign ReadTag = ReadPAdr[`XLEN-1:SETWIDTH+OFFSETWIDTH];
 | 
				
			||||||
 | 
					        // Write address
 | 
				
			||||||
 | 
					        assign WriteSet = WritePAdr[SETWIDTH+OFFSETWIDTH-1:OFFSETWIDTH];
 | 
				
			||||||
 | 
					        assign WriteTag = WritePAdr[`XLEN-1:SETWIDTH+OFFSETWIDTH];
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    genvar i;
 | 
				
			||||||
 | 
					    generate
 | 
				
			||||||
 | 
					        for (i=0; i < NUMLINES; i++) begin
 | 
				
			||||||
 | 
					            rocacheline #(LINESIZE, TAGWIDTH, WORDSIZE) lines (
 | 
				
			||||||
 | 
					                .*,
 | 
				
			||||||
 | 
					                .WriteEnable(WriteEnable & (WriteSet == i)),
 | 
				
			||||||
 | 
					                .WriteData(WriteLine),
 | 
				
			||||||
 | 
					                .WriteTag(WriteTag),
 | 
				
			||||||
 | 
					                .DataWord(LineOutputs[i]),
 | 
				
			||||||
 | 
					                .DataTag(TagOutputs[i]),
 | 
				
			||||||
 | 
					                .DataValid(ValidOutputs[i])
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					    endgenerate
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Get the data and valid out of the lines
 | 
				
			||||||
 | 
					    always_comb begin
 | 
				
			||||||
 | 
					        assign DataWord = LineOutputs[ReadSet];
 | 
				
			||||||
 | 
					        assign DataValid = ValidOutputs[ReadSet] & (TagOutputs[ReadSet] == ReadTag);
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					endmodule
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										68
									
								
								wally-pipelined/src/cache/line.sv
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								wally-pipelined/src/cache/line.sv
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,68 @@
 | 
				
			|||||||
 | 
					///////////////////////////////////////////
 | 
				
			||||||
 | 
					// line.sv
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Written: jaallen@g.hmc.edu 2021-03-23
 | 
				
			||||||
 | 
					// Modified: 
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Purpose: An implementation of a single cache line
 | 
				
			||||||
 | 
					// 
 | 
				
			||||||
 | 
					// 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"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// A read-only cache line ("write"ing to this line is loading new data, not writing to memory
 | 
				
			||||||
 | 
					module rocacheline #(parameter LINESIZE = 256, parameter TAGSIZE = 32, parameter WORDSIZE = `XLEN) (
 | 
				
			||||||
 | 
					    // Pipeline stuff
 | 
				
			||||||
 | 
					    input  logic clk,
 | 
				
			||||||
 | 
					    input  logic reset,
 | 
				
			||||||
 | 
					    // If flush is high, invalidate this word
 | 
				
			||||||
 | 
					    input  logic flush,
 | 
				
			||||||
 | 
					    // Select which word within the line
 | 
				
			||||||
 | 
					    input  logic [$clog2(LINESIZE/8)-1:0]   WordSelect,
 | 
				
			||||||
 | 
					    // Write new data to the line
 | 
				
			||||||
 | 
					    input  logic                            WriteEnable,
 | 
				
			||||||
 | 
					    input  logic [LINESIZE-1:0]             WriteData,
 | 
				
			||||||
 | 
					    input  logic [TAGSIZE-1:0]              WriteTag,
 | 
				
			||||||
 | 
					    // Output the word, as well as the tag and if it is valid
 | 
				
			||||||
 | 
					    output logic [WORDSIZE-1:0]             DataWord,
 | 
				
			||||||
 | 
					    output logic [TAGSIZE-1:0]              DataTag,
 | 
				
			||||||
 | 
					    output logic                            DataValid
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    localparam integer OFFSETSIZE = $clog2(LINESIZE/8);
 | 
				
			||||||
 | 
					    localparam integer NUMWORDS = LINESIZE/WORDSIZE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    logic [NUMWORDS-1:0][WORDSIZE-1:0]  DataLinesIn, DataLinesOut;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    flopenr #(1)        ValidBitFlop(clk, reset, WriteEnable | flush, ~flush, DataValid);
 | 
				
			||||||
 | 
					    flopenr #(TAGSIZE)  TagFlop(clk, reset, WriteEnable, WriteTag, DataTag);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    genvar i;
 | 
				
			||||||
 | 
					    generate
 | 
				
			||||||
 | 
					        for (i=0; i < NUMWORDS; i++) begin
 | 
				
			||||||
 | 
					            assign DataLinesIn[i] = WriteData[NUMWORDS*i+WORDSIZE-1:NUMWORDS*i];
 | 
				
			||||||
 | 
					            flopenr #(LINESIZE) LineFlop(clk, reset, WriteEnable, DataLinesIn[i], DataLinesOut[i]);
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					    endgenerate
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    always_comb begin
 | 
				
			||||||
 | 
					        assign DataWord = DataLinesOut[WordSelect[OFFSETSIZE-1:$clog2(WORDSIZE)]];
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					endmodule
 | 
				
			||||||
@ -29,7 +29,7 @@ module hazard(
 | 
				
			|||||||
  // Detect hazards
 | 
					  // Detect hazards
 | 
				
			||||||
  input  logic       BPPredWrongE, CSRWritePendingDEM, RetM, TrapM,
 | 
					  input  logic       BPPredWrongE, CSRWritePendingDEM, RetM, TrapM,
 | 
				
			||||||
  input  logic       LoadStallD, MulDivStallD, CSRRdStallD,
 | 
					  input  logic       LoadStallD, MulDivStallD, CSRRdStallD,
 | 
				
			||||||
  input  logic       InstrStall, DataStall,
 | 
					  input  logic       InstrStall, DataStall, ICacheStallF,
 | 
				
			||||||
  // Stall & flush outputs
 | 
					  // Stall & flush outputs
 | 
				
			||||||
  output logic       StallF, StallD, StallE, StallM, StallW,
 | 
					  output logic       StallF, StallD, StallE, StallM, StallW,
 | 
				
			||||||
  output logic       FlushF, FlushD, FlushE, FlushM, FlushW
 | 
					  output logic       FlushF, FlushD, FlushE, FlushM, FlushW
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										138
									
								
								wally-pipelined/src/ifu/icache.sv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								wally-pipelined/src/ifu/icache.sv
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,138 @@
 | 
				
			|||||||
 | 
					///////////////////////////////////////////
 | 
				
			||||||
 | 
					// icache.sv
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Written: jaallen@g.hmc.edu 2021-03-02
 | 
				
			||||||
 | 
					// Modified: 
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Purpose: Cache instructions for the ifu so it can access memory less often, saving cycles
 | 
				
			||||||
 | 
					// 
 | 
				
			||||||
 | 
					// 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 icache(
 | 
				
			||||||
 | 
					  // Basic pipeline stuff
 | 
				
			||||||
 | 
					  input  logic              clk, reset,
 | 
				
			||||||
 | 
					  input  logic              StallF, StallD,
 | 
				
			||||||
 | 
					  input  logic              FlushD,
 | 
				
			||||||
 | 
					  // Upper bits of physical address for PC
 | 
				
			||||||
 | 
					  input  logic [`XLEN-1:12] UpperPCPF,
 | 
				
			||||||
 | 
					  // Lower 12 bits of virtual PC address, since it's faster this way
 | 
				
			||||||
 | 
					  input  logic [11:0]       LowerPCF,
 | 
				
			||||||
 | 
					  // Data read in from the ebu unit
 | 
				
			||||||
 | 
					  input  logic [`XLEN-1:0]  InstrInF,
 | 
				
			||||||
 | 
					  // Read requested from the ebu unit
 | 
				
			||||||
 | 
					  output logic [`XLEN-1:0]  InstrPAdrF,
 | 
				
			||||||
 | 
					  output logic              InstrReadF,
 | 
				
			||||||
 | 
					  // High if the instruction currently in the fetch stage is compressed
 | 
				
			||||||
 | 
					  output logic              CompressedF,
 | 
				
			||||||
 | 
					  // High if the icache is requesting a stall
 | 
				
			||||||
 | 
					  output logic              ICacheStallF,
 | 
				
			||||||
 | 
					  // The raw (not decompressed) instruction that was requested
 | 
				
			||||||
 | 
					  // If the next instruction is compressed, the upper 16 bits may be anything
 | 
				
			||||||
 | 
					  output logic [31:0]       InstrRawD
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    logic             DelayF, DelaySideF, FlushDLastCyclen, DelayD;
 | 
				
			||||||
 | 
					    logic  [1:0]      InstrDMuxChoice;
 | 
				
			||||||
 | 
					    logic [15:0]      MisalignedHalfInstrF, MisalignedHalfInstrD;
 | 
				
			||||||
 | 
					    logic [31:0]      InstrF, AlignedInstrD;
 | 
				
			||||||
 | 
					    // Buffer the last read, for ease of accessing it again
 | 
				
			||||||
 | 
					    logic             LastReadDataValidF;
 | 
				
			||||||
 | 
					    logic [`XLEN-1:0] LastReadDataF, LastReadAdrF, InDataF;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // instruction for NOP
 | 
				
			||||||
 | 
					    logic [31:0]      nop = 32'h00000013;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Temporary change to bridge the new interface to old behaviors
 | 
				
			||||||
 | 
					    logic [`XLEN-1:0] PCPF;
 | 
				
			||||||
 | 
					    assign PCPF = {UpperPCPF, LowerPCF};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // This flop doesn't stall if StallF is high because we should output a nop
 | 
				
			||||||
 | 
					    // when FlushD happens, even if the pipeline is also stalled.
 | 
				
			||||||
 | 
					    flopr   #(1)  flushDLastCycleFlop(clk, reset, ~FlushD & (FlushDLastCyclen | ~StallF), FlushDLastCyclen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    flopenr #(1)  delayDFlop(clk, reset, ~StallF, DelayF & ~CompressedF, DelayD);
 | 
				
			||||||
 | 
					    flopenrc#(1)  delayStateFlop(clk, reset, FlushD, ~StallF, DelayF & ~DelaySideF, DelaySideF);
 | 
				
			||||||
 | 
					    // This flop stores the first half of a misaligned instruction while waiting for the other half
 | 
				
			||||||
 | 
					    flopenr #(16) halfInstrFlop(clk, reset, DelayF & ~StallF, MisalignedHalfInstrF, MisalignedHalfInstrD);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // This flop is here to simulate pulling data out of the cache, which is edge-triggered
 | 
				
			||||||
 | 
					    flopenr #(32) instrFlop(clk, reset, ~StallF, InstrF, AlignedInstrD);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // These flops cache the previous read, to accelerate things
 | 
				
			||||||
 | 
					    flopenr #(`XLEN) lastReadDataFlop(clk, reset, InstrReadF & ~StallF, InstrInF, LastReadDataF);
 | 
				
			||||||
 | 
					    flopenr #(1)     lastReadDataVFlop(clk, reset, InstrReadF & ~StallF, 1'b1, LastReadDataValidF);
 | 
				
			||||||
 | 
					    flopenr #(`XLEN) lastReadAdrFlop(clk, reset, InstrReadF & ~StallF, InstrPAdrF, LastReadAdrF);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Decide which address needs to be fetched and sent out over InstrPAdrF
 | 
				
			||||||
 | 
					    // If the requested address fits inside one read from memory, we fetch that
 | 
				
			||||||
 | 
					    // address, adjusted to the bit width. Otherwise, we request the lower word
 | 
				
			||||||
 | 
					    // and then the upper word, in that order.
 | 
				
			||||||
 | 
					    generate
 | 
				
			||||||
 | 
					        if (`XLEN == 32) begin
 | 
				
			||||||
 | 
					            assign InstrPAdrF = PCPF[1] ? ((DelaySideF & ~CompressedF) ? {PCPF[31:2], 2'b00} : {PCPF[31:2], 2'b00}) : PCPF;
 | 
				
			||||||
 | 
					        end else begin
 | 
				
			||||||
 | 
					            assign InstrPAdrF = PCPF[2] ? (PCPF[1] ? ((DelaySideF & ~CompressedF) ? {PCPF[63:3]+1, 3'b000} : {PCPF[63:3], 3'b000}) : {PCPF[63:3], 3'b000}) : {PCPF[63:3], 3'b000};
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					    endgenerate
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Read from memory if we don't have the address we want
 | 
				
			||||||
 | 
					    always_comb if (LastReadDataValidF & (InstrPAdrF == LastReadAdrF)) begin
 | 
				
			||||||
 | 
					        assign InstrReadF = 0;
 | 
				
			||||||
 | 
					    end else begin
 | 
				
			||||||
 | 
					        assign InstrReadF = 1;
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Pick from the memory input or from the previous read, as appropriate
 | 
				
			||||||
 | 
					    mux2 #(`XLEN) inDataMux(LastReadDataF, InstrInF, InstrReadF, InDataF);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // If the instruction fits in one memory read, then we put the right bits
 | 
				
			||||||
 | 
					    // into InstrF. Otherwise, we activate DelayF to signal the rest of the
 | 
				
			||||||
 | 
					    // machinery to swizzle bits.
 | 
				
			||||||
 | 
					    generate
 | 
				
			||||||
 | 
					        if (`XLEN == 32) begin
 | 
				
			||||||
 | 
					            assign InstrF = PCPF[1] ? {16'b0, InDataF[31:16]} : InDataF;
 | 
				
			||||||
 | 
					            assign DelayF = PCPF[1];
 | 
				
			||||||
 | 
					            assign MisalignedHalfInstrF = InDataF[31:16];
 | 
				
			||||||
 | 
					        end else begin
 | 
				
			||||||
 | 
					            assign InstrF = PCPF[2] ? (PCPF[1] ? {16'b0, InDataF[63:48]}  : InDataF[63:32]) : (PCPF[1] ? InDataF[47:16] : InDataF[31:0]);
 | 
				
			||||||
 | 
					            assign DelayF = PCPF[1] && PCPF[2];
 | 
				
			||||||
 | 
					            assign MisalignedHalfInstrF = InDataF[63:48];
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					    endgenerate
 | 
				
			||||||
 | 
					    // We will likely need to stall later, but stalls are handled by the rest of the pipeline for now
 | 
				
			||||||
 | 
					    assign ICacheStallF = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Detect if the instruction is compressed
 | 
				
			||||||
 | 
					    assign CompressedF = InstrF[1:0] != 2'b11;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Pick the correct output, depending on whether we have to assemble this
 | 
				
			||||||
 | 
					    // instruction from two reads or not.
 | 
				
			||||||
 | 
					    // Output the requested instruction (we don't need to worry if the read is
 | 
				
			||||||
 | 
					    // incomplete, since the pipeline stalls for us when it isn't), or a NOP for
 | 
				
			||||||
 | 
					    // the cycle when the first of two reads comes in.
 | 
				
			||||||
 | 
					    always_comb if (~FlushDLastCyclen) begin
 | 
				
			||||||
 | 
					        assign InstrDMuxChoice = 2'b10;
 | 
				
			||||||
 | 
					    end else if (DelayD & (MisalignedHalfInstrD[1:0] != 2'b11)) begin
 | 
				
			||||||
 | 
					        assign InstrDMuxChoice = 2'b11;
 | 
				
			||||||
 | 
					    end else begin
 | 
				
			||||||
 | 
					        assign InstrDMuxChoice = {1'b0, DelayD};
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					    mux4 #(32) instrDMux (AlignedInstrD, {InstrInF[15:0], MisalignedHalfInstrD}, nop, {16'b0, MisalignedHalfInstrD}, InstrDMuxChoice, InstrRawD);
 | 
				
			||||||
 | 
					endmodule
 | 
				
			||||||
@ -2,7 +2,7 @@
 | 
				
			|||||||
// ifu.sv
 | 
					// ifu.sv
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Written: David_Harris@hmc.edu 9 January 2021
 | 
					// Written: David_Harris@hmc.edu 9 January 2021
 | 
				
			||||||
// Modified: 
 | 
					// Modified:
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Purpose: Instrunction Fetch Unit
 | 
					// Purpose: Instrunction Fetch Unit
 | 
				
			||||||
//           PC, branch prediction, instruction cache
 | 
					//           PC, branch prediction, instruction cache
 | 
				
			||||||
@ -35,6 +35,7 @@ module ifu (
 | 
				
			|||||||
  output logic [`XLEN-1:0] PCF, 
 | 
					  output logic [`XLEN-1:0] PCF, 
 | 
				
			||||||
  output logic [`XLEN-1:0] InstrPAdrF,
 | 
					  output logic [`XLEN-1:0] InstrPAdrF,
 | 
				
			||||||
  output logic             InstrReadF,
 | 
					  output logic             InstrReadF,
 | 
				
			||||||
 | 
					  output logic             ICacheStallF,
 | 
				
			||||||
  // Decode  
 | 
					  // Decode  
 | 
				
			||||||
  // Execute
 | 
					  // Execute
 | 
				
			||||||
  output logic [`XLEN-1:0] PCLinkE,
 | 
					  output logic [`XLEN-1:0] PCLinkE,
 | 
				
			||||||
@ -61,27 +62,25 @@ module ifu (
 | 
				
			|||||||
  input logic  [`XLEN-1:0] PageTableEntryF,
 | 
					  input logic  [`XLEN-1:0] PageTableEntryF,
 | 
				
			||||||
  input logic  [`XLEN-1:0] SATP_REGW,
 | 
					  input logic  [`XLEN-1:0] SATP_REGW,
 | 
				
			||||||
  input logic              ITLBWriteF, // ITLBFlushF,
 | 
					  input logic              ITLBWriteF, // ITLBFlushF,
 | 
				
			||||||
  output logic             ITLBMissF, ITLBHitF,
 | 
					  output logic             ITLBMissF, ITLBHitF
 | 
				
			||||||
  // bogus
 | 
					 | 
				
			||||||
  input  logic [15:0] rd2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  logic [`XLEN-1:0] UnalignedPCNextF, PCNextF;
 | 
					  logic [`XLEN-1:0] UnalignedPCNextF, PCNextF;
 | 
				
			||||||
  logic misaligned, BranchMisalignedFaultE, BranchMisalignedFaultM, TrapMisalignedFaultM;
 | 
					  logic             misaligned, BranchMisalignedFaultE, BranchMisalignedFaultM, TrapMisalignedFaultM;
 | 
				
			||||||
  logic PrivilegedChangePCM;
 | 
					  logic             PrivilegedChangePCM;
 | 
				
			||||||
  logic IllegalCompInstrD;
 | 
					  logic             IllegalCompInstrD;
 | 
				
			||||||
  logic [`XLEN-1:0] PCPlusUpperF, PCPlus2or4F, PCD, PCLinkD, PCLinkM;
 | 
					  logic [`XLEN-1:0] PCPlusUpperF, PCPlus2or4F, PCD, PCW, PCLinkD, PCLinkM, PCPF;
 | 
				
			||||||
  logic        CompressedF;
 | 
					  logic             CompressedF;
 | 
				
			||||||
  logic [31:0]     InstrF, InstrRawD, InstrE;
 | 
					  logic [31:0]      InstrRawD, InstrE, InstrW;
 | 
				
			||||||
  logic [31:0]     nop = 32'h00000013; // instruction for NOP
 | 
					  logic [31:0]      nop = 32'h00000013; // instruction for NOP
 | 
				
			||||||
 | 
					  logic [`XLEN-1:0] ITLBInstrPAdrF, ICacheInstrPAdrF;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // *** temporary hack until walker is hooked up -- Thomas F
 | 
					  // *** temporary hack until walker is hooked up -- Thomas F
 | 
				
			||||||
  // logic  [`XLEN-1:0] PageTableEntryF = '0;
 | 
					  // logic  [`XLEN-1:0] PageTableEntryF = '0;
 | 
				
			||||||
  logic ITLBFlushF = '0;
 | 
					  logic ITLBFlushF = '0;
 | 
				
			||||||
  // logic ITLBWriteF = '0;
 | 
					  // logic ITLBWriteF = '0;
 | 
				
			||||||
  tlb #(3) itlb(clk, reset, SATP_REGW, PrivilegeModeW, PCF, PageTableEntryF, ITLBWriteF, ITLBFlushF,
 | 
					  tlb #(3) itlb(clk, reset, SATP_REGW, PrivilegeModeW, PCF, PageTableEntryF, ITLBWriteF, ITLBFlushF,
 | 
				
			||||||
    InstrPAdrF, ITLBMissF, ITLBHitF);
 | 
					    ITLBInstrPAdrF, ITLBMissF, ITLBHitF);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // branch predictor signals
 | 
					  // branch predictor signals
 | 
				
			||||||
  logic 	   SelBPPredF;
 | 
					  logic 	   SelBPPredF;
 | 
				
			||||||
@ -92,11 +91,21 @@ module ifu (
 | 
				
			|||||||
  // *** put memory interface on here, InstrF becomes output
 | 
					  // *** put memory interface on here, InstrF becomes output
 | 
				
			||||||
  //assign InstrPAdrF = PCF; // *** no MMU
 | 
					  //assign InstrPAdrF = PCF; // *** no MMU
 | 
				
			||||||
  //assign InstrReadF = ~StallD; // *** & ICacheMissF; add later
 | 
					  //assign InstrReadF = ~StallD; // *** & ICacheMissF; add later
 | 
				
			||||||
  assign InstrReadF = 1; // *** & ICacheMissF; add later
 | 
					  // assign InstrReadF = 1; // *** & ICacheMissF; add later
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // jarred 2021-03-14 Add instrution cache block to remove rd2
 | 
				
			||||||
 | 
					  assign PCPF = PCF; // Temporary workaround until iTLB is live
 | 
				
			||||||
 | 
					  icache ic(
 | 
				
			||||||
 | 
					    .*,
 | 
				
			||||||
 | 
					    .InstrPAdrF(ICacheInstrPAdrF),
 | 
				
			||||||
 | 
					    .UpperPCPF(PCPF[`XLEN-1:12]),
 | 
				
			||||||
 | 
					    .LowerPCF(PCF[11:0])
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					  // Prioritize the iTLB for reads if it wants one
 | 
				
			||||||
 | 
					  mux2 #(`XLEN) instrPAdrMux(ICacheInstrPAdrF, ITLBInstrPAdrF, ITLBMissF, InstrPAdrF);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  assign PrivilegedChangePCM = RetM | TrapM;
 | 
					  assign PrivilegedChangePCM = RetM | TrapM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
  //mux3    #(`XLEN) pcmux(PCPlus2or4F, PCCorrectE, PrivilegedNextPCM, {PrivilegedChangePCM, BPPredWrongE}, UnalignedPCNextF);
 | 
					  //mux3    #(`XLEN) pcmux(PCPlus2or4F, PCCorrectE, PrivilegedNextPCM, {PrivilegedChangePCM, BPPredWrongE}, UnalignedPCNextF);
 | 
				
			||||||
  mux2 #(`XLEN) pcmux0(.d0(PCPlus2or4F),
 | 
					  mux2 #(`XLEN) pcmux0(.d0(PCPlus2or4F),
 | 
				
			||||||
		       .d1(BPPredPCF),
 | 
							       .d1(BPPredPCF),
 | 
				
			||||||
@ -114,7 +123,7 @@ module ifu (
 | 
				
			|||||||
		       .y(UnalignedPCNextF));
 | 
							       .y(UnalignedPCNextF));
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  assign  PCNextF = {UnalignedPCNextF[`XLEN-1:1], 1'b0}; // hart-SPEC p. 21 about 16-bit alignment
 | 
					  assign  PCNextF = {UnalignedPCNextF[`XLEN-1:1], 1'b0}; // hart-SPEC p. 21 about 16-bit alignment
 | 
				
			||||||
  flopenl #(`XLEN) pcreg(clk, reset, ~StallF, PCNextF, `RESET_VECTOR, PCF);
 | 
					  flopenl #(`XLEN) pcreg(clk, reset, ~StallF & ~ICacheStallF, PCNextF, `RESET_VECTOR, PCF);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // branch and jump predictor
 | 
					  // branch and jump predictor
 | 
				
			||||||
  // I am making the port connection explicit for now as I want to see them and they will be changing.
 | 
					  // I am making the port connection explicit for now as I want to see them and they will be changing.
 | 
				
			||||||
@ -141,9 +150,7 @@ module ifu (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  // pcadder
 | 
					  // pcadder
 | 
				
			||||||
  // add 2 or 4 to the PC, based on whether the instruction is 16 bits or 32
 | 
					  // add 2 or 4 to the PC, based on whether the instruction is 16 bits or 32
 | 
				
			||||||
  assign CompressedF = (InstrF[1:0] != 2'b11); // is it a 16-bit compressed instruction?
 | 
					 | 
				
			||||||
  assign PCPlusUpperF = PCF[`XLEN-1:2] + 1; // add 4 to PC
 | 
					  assign PCPlusUpperF = PCF[`XLEN-1:2] + 1; // add 4 to PC
 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  // choose PC+2 or PC+4
 | 
					  // choose PC+2 or PC+4
 | 
				
			||||||
  always_comb
 | 
					  always_comb
 | 
				
			||||||
    if (CompressedF) // add 2
 | 
					    if (CompressedF) // add 2
 | 
				
			||||||
@ -151,18 +158,7 @@ module ifu (
 | 
				
			|||||||
      else        PCPlus2or4F = {PCF[`XLEN-1:2], 2'b10};
 | 
					      else        PCPlus2or4F = {PCF[`XLEN-1:2], 2'b10};
 | 
				
			||||||
    else          PCPlus2or4F = {PCPlusUpperF, PCF[1:0]}; // add 4
 | 
					    else          PCPlus2or4F = {PCPlusUpperF, PCF[1:0]}; // add 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // harris 2/23/21 Add code to fetch instruction split across two words
 | 
					 | 
				
			||||||
  generate 
 | 
					 | 
				
			||||||
    if (`XLEN==32) begin
 | 
					 | 
				
			||||||
      assign InstrF = PCF[1] ? {rd2[15:0], InstrInF[31:16]} : InstrInF;
 | 
					 | 
				
			||||||
    end else begin
 | 
					 | 
				
			||||||
      assign InstrF = PCF[2] ? (PCF[1] ? {rd2[15:0], InstrInF[63:48]} : InstrInF[63:32])
 | 
					 | 
				
			||||||
                          : (PCF[1] ? InstrInF[47:16] : InstrInF[31:0]);
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
  endgenerate
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Decode stage pipeline register and logic
 | 
					  // Decode stage pipeline register and logic
 | 
				
			||||||
  flopenl #(32)    InstrDReg(clk, reset, ~StallD | FlushD, (FlushD ? nop : InstrF), nop, InstrRawD);
 | 
					 | 
				
			||||||
  flopenrc #(`XLEN) PCDReg(clk, reset, FlushD, ~StallD, PCF, PCD);
 | 
					  flopenrc #(`XLEN) PCDReg(clk, reset, FlushD, ~StallD, PCF, PCD);
 | 
				
			||||||
   
 | 
					   
 | 
				
			||||||
  // expand 16-bit compressed instructions to 32 bits
 | 
					  // expand 16-bit compressed instructions to 32 bits
 | 
				
			||||||
 | 
				
			|||||||
@ -98,6 +98,8 @@ module wallypipelinedhart (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  logic [`XLEN-1:0] PageTableEntryF, PageTableEntryM;
 | 
					  logic [`XLEN-1:0] PageTableEntryF, PageTableEntryM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // IMem stalls
 | 
				
			||||||
 | 
					  logic             ICacheStallF;
 | 
				
			||||||
  logic [`XLEN-1:0] MMUPAdr, MMUReadPTE;
 | 
					  logic [`XLEN-1:0] MMUPAdr, MMUReadPTE;
 | 
				
			||||||
  logic             MMUTranslate, MMUTranslationComplete, MMUReady;
 | 
					  logic             MMUTranslate, MMUTranslationComplete, MMUReady;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -7,7 +7,7 @@ module testbench_busybear();
 | 
				
			|||||||
  logic [31:0]     GPIOPinsOut, GPIOPinsEn;
 | 
					  logic [31:0]     GPIOPinsOut, GPIOPinsEn;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // instantiate device to be tested
 | 
					  // instantiate device to be tested
 | 
				
			||||||
  logic [31:0] CheckInstrF;
 | 
					  logic [31:0] CheckInstrD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  logic [`AHBW-1:0] HRDATA;
 | 
					  logic [`AHBW-1:0] HRDATA;
 | 
				
			||||||
  logic [31:0]      HADDR;
 | 
					  logic [31:0]      HADDR;
 | 
				
			||||||
@ -194,8 +194,8 @@ module testbench_busybear();
 | 
				
			|||||||
  logic [`XLEN-1:0] readAdrExpected;
 | 
					  logic [`XLEN-1:0] readAdrExpected;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  always @(dut.HRDATA) begin
 | 
					  always @(dut.HRDATA) begin
 | 
				
			||||||
    #1;
 | 
					    #2;
 | 
				
			||||||
    if (dut.hart.MemRWM[1] && ~HWRITE && HADDR != dut.PCF && dut.HRDATA !== {64{1'bx}}) begin
 | 
					    if (dut.hart.MemRWM[1] && ~HWRITE && HADDR[31:3] != dut.PCF[31:3] && dut.HRDATA !== {64{1'bx}}) begin
 | 
				
			||||||
      //$display("%0t", $time);
 | 
					      //$display("%0t", $time);
 | 
				
			||||||
      if($feof(data_file_memR)) begin
 | 
					      if($feof(data_file_memR)) begin
 | 
				
			||||||
        $display("no more memR data to read");
 | 
					        $display("no more memR data to read");
 | 
				
			||||||
@ -265,7 +265,7 @@ module testbench_busybear();
 | 
				
			|||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  always @(dut.hart.priv.csr.genblk1.csrm.MCAUSE_REGW) begin
 | 
					  always @(dut.hart.priv.csr.genblk1.csrm.MCAUSE_REGW) begin
 | 
				
			||||||
    if (dut.hart.priv.csr.genblk1.csrm.MCAUSE_REGW == 2 && instrs != 0) begin
 | 
					    if (dut.hart.priv.csr.genblk1.csrm.MCAUSE_REGW == 2 && instrs > 1) begin
 | 
				
			||||||
      $display("!!!!!! illegal instruction !!!!!!!!!!");
 | 
					      $display("!!!!!! illegal instruction !!!!!!!!!!");
 | 
				
			||||||
      $display("(as a reminder, MCAUSE and MEPC are set by this)");
 | 
					      $display("(as a reminder, MCAUSE and MEPC are set by this)");
 | 
				
			||||||
      $display("at %0t ps, instr %0d, HADDR %x", $time, instrs, HADDR);
 | 
					      $display("at %0t ps, instr %0d, HADDR %x", $time, instrs, HADDR);
 | 
				
			||||||
@ -337,7 +337,7 @@ module testbench_busybear();
 | 
				
			|||||||
  `CHECK_CSR(STVEC)
 | 
					  `CHECK_CSR(STVEC)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  initial begin //this is temporary until the bug can be fixed!!!
 | 
					  initial begin //this is temporary until the bug can be fixed!!!
 | 
				
			||||||
    #18909760;
 | 
					    #11130100;
 | 
				
			||||||
    force dut.hart.ieu.dp.regf.rf[5] = 64'h0000000080000004;
 | 
					    force dut.hart.ieu.dp.regf.rf[5] = 64'h0000000080000004;
 | 
				
			||||||
    #100;
 | 
					    #100;
 | 
				
			||||||
    release dut.hart.ieu.dp.regf.rf[5];
 | 
					    release dut.hart.ieu.dp.regf.rf[5];
 | 
				
			||||||
@ -347,7 +347,7 @@ module testbench_busybear();
 | 
				
			|||||||
  initial begin
 | 
					  initial begin
 | 
				
			||||||
    speculative = 0;
 | 
					    speculative = 0;
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
  logic [63:0] lastCheckInstrF, lastPC, lastPC2;
 | 
					  logic [63:0] lastCheckInstrD, lastPC, lastPC2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  string PCtextW, PCtext2W;
 | 
					  string PCtextW, PCtext2W;
 | 
				
			||||||
  logic [31:0] InstrWExpected;
 | 
					  logic [31:0] InstrWExpected;
 | 
				
			||||||
@ -382,102 +382,102 @@ module testbench_busybear();
 | 
				
			|||||||
  end
 | 
					  end
 | 
				
			||||||
  logic [31:0] InstrMask;
 | 
					  logic [31:0] InstrMask;
 | 
				
			||||||
  logic forcedInstr;
 | 
					  logic forcedInstr;
 | 
				
			||||||
  logic [63:0] lastPCF;
 | 
					  logic [63:0] lastPCD;
 | 
				
			||||||
  always @(dut.PCF or dut.hart.ifu.InstrF or reset) begin
 | 
					  always @(dut.hart.ifu.PCD or dut.hart.ifu.InstrRawD or reset or negedge dut.hart.ifu.StallE) begin
 | 
				
			||||||
    if(~HWRITE) begin
 | 
					    if(~HWRITE) begin
 | 
				
			||||||
    #3;
 | 
					      #2;
 | 
				
			||||||
    if (~reset && dut.hart.ifu.InstrF[15:0] !== {16{1'bx}} && ~dut.hart.StallD) begin
 | 
					      if (~reset && dut.hart.ifu.InstrRawD[15:0] !== {16{1'bx}} && dut.hart.ifu.PCD !== 64'h0 && ~dut.hart.ifu.StallE) begin
 | 
				
			||||||
      if (dut.PCF !== lastPCF) begin
 | 
					        if (dut.hart.ifu.PCD !== lastPCD) begin
 | 
				
			||||||
        lastCheckInstrF = CheckInstrF;
 | 
					          lastCheckInstrD = CheckInstrD;
 | 
				
			||||||
        lastPC <= dut.PCF;
 | 
					          lastPC <= dut.hart.ifu.PCD;
 | 
				
			||||||
        lastPC2 <= lastPC;
 | 
					          lastPC2 <= lastPC;
 | 
				
			||||||
        if (speculative && (lastPC != pcExpected)) begin
 | 
					          if (speculative && (lastPC != pcExpected)) begin
 | 
				
			||||||
          speculative = ~equal(dut.PCF,pcExpected,3);
 | 
					            speculative = ~equal(dut.hart.ifu.PCD,pcExpected,3);
 | 
				
			||||||
          if(dut.PCF===pcExpected) begin
 | 
					            if(dut.hart.ifu.PCD===pcExpected) begin
 | 
				
			||||||
            if(dut.hart.ifu.InstrF[6:0] == 7'b1010011) begin // for now, NOP out any float instrs
 | 
					              if(dut.hart.ifu.InstrRawD[6:0] == 7'b1010011) begin // for now, NOP out any float instrs
 | 
				
			||||||
              force CheckInstrF = 32'b0010011;
 | 
					                force CheckInstrD = 32'b0010011;
 | 
				
			||||||
              release CheckInstrF;
 | 
					                release CheckInstrD;
 | 
				
			||||||
              force dut.hart.ifu.InstrF = 32'b0010011;
 | 
					                force dut.hart.ifu.InstrRawD = 32'b0010011;
 | 
				
			||||||
              #7;
 | 
					                #7;
 | 
				
			||||||
              release dut.hart.ifu.InstrF;
 | 
					                release dut.hart.ifu.InstrRawD;
 | 
				
			||||||
              $display("warning: NOPing out %s at PC=%0x, instr %0d, time %0t", PCtext, dut.PCF, instrs, $time);
 | 
					                $display("warning: NOPing out %s at PC=%0x, instr %0d, time %0t", PCtext, dut.hart.ifu.PCD, instrs, $time);
 | 
				
			||||||
              warningCount += 1;
 | 
					                warningCount += 1;
 | 
				
			||||||
              forcedInstr = 1;
 | 
					                forcedInstr = 1;
 | 
				
			||||||
            end
 | 
					              end
 | 
				
			||||||
            else begin
 | 
					              else begin
 | 
				
			||||||
              forcedInstr = 0;
 | 
					                forcedInstr = 0;
 | 
				
			||||||
 | 
					              end
 | 
				
			||||||
            end
 | 
					            end
 | 
				
			||||||
          end
 | 
					          end
 | 
				
			||||||
        end
 | 
					          else begin
 | 
				
			||||||
        else begin
 | 
					            if($feof(data_file_PC)) begin
 | 
				
			||||||
          if($feof(data_file_PC)) begin
 | 
					              $display("no more PC data to read");
 | 
				
			||||||
            $display("no more PC data to read");
 | 
					              `ERROR
 | 
				
			||||||
            `ERROR
 | 
					 | 
				
			||||||
          end
 | 
					 | 
				
			||||||
          scan_file_PC = $fscanf(data_file_PC, "%s\n", PCtext);
 | 
					 | 
				
			||||||
          if (PCtext != "ret" && PCtext != "fence" && PCtext != "nop" && PCtext != "mret" && PCtext != "sfence.vma" && PCtext != "unimp") begin
 | 
					 | 
				
			||||||
            scan_file_PC = $fscanf(data_file_PC, "%s\n", PCtext2);
 | 
					 | 
				
			||||||
            PCtext = {PCtext, " ", PCtext2};
 | 
					 | 
				
			||||||
          end
 | 
					 | 
				
			||||||
          scan_file_PC = $fscanf(data_file_PC, "%x\n", CheckInstrF);
 | 
					 | 
				
			||||||
          if(dut.PCF === pcExpected) begin
 | 
					 | 
				
			||||||
            if(dut.hart.ifu.InstrF[6:0] == 7'b1010011) begin // for now, NOP out any float instrs
 | 
					 | 
				
			||||||
              force CheckInstrF = 32'b0010011;
 | 
					 | 
				
			||||||
              release CheckInstrF;
 | 
					 | 
				
			||||||
              force dut.hart.ifu.InstrF = 32'b0010011;
 | 
					 | 
				
			||||||
              #7;
 | 
					 | 
				
			||||||
              release dut.hart.ifu.InstrF;
 | 
					 | 
				
			||||||
              $display("warning: NOPing out %s at PC=%0x, instr %0d, time %0t", PCtext, dut.PCF, instrs, $time);
 | 
					 | 
				
			||||||
              warningCount += 1;
 | 
					 | 
				
			||||||
              forcedInstr = 1;
 | 
					 | 
				
			||||||
            end
 | 
					            end
 | 
				
			||||||
            else begin
 | 
					            scan_file_PC = $fscanf(data_file_PC, "%s\n", PCtext);
 | 
				
			||||||
              forcedInstr = 0;
 | 
					            if (PCtext != "ret" && PCtext != "fence" && PCtext != "nop" && PCtext != "mret" && PCtext != "sfence.vma" && PCtext != "unimp") begin
 | 
				
			||||||
 | 
					              scan_file_PC = $fscanf(data_file_PC, "%s\n", PCtext2);
 | 
				
			||||||
 | 
					              PCtext = {PCtext, " ", PCtext2};
 | 
				
			||||||
            end
 | 
					            end
 | 
				
			||||||
          end
 | 
					            scan_file_PC = $fscanf(data_file_PC, "%x\n", CheckInstrD);
 | 
				
			||||||
          // then expected PC value
 | 
					            if(dut.hart.ifu.PCD === pcExpected) begin
 | 
				
			||||||
          scan_file_PC = $fscanf(data_file_PC, "%x\n", pcExpected);
 | 
					              if(dut.hart.ifu.InstrRawD[6:0] == 7'b1010011) begin // for now, NOP out any float instrs
 | 
				
			||||||
          if (instrs <= 10 || (instrs <= 100 && instrs % 10 == 0) ||
 | 
					                force CheckInstrD = 32'b0010011;
 | 
				
			||||||
             (instrs <= 1000 && instrs % 100 == 0) || (instrs <= 10000 && instrs % 1000 == 0) ||
 | 
					                release CheckInstrD;
 | 
				
			||||||
             (instrs <= 100000 && instrs % 10000 == 0) || (instrs <= 1000000 && instrs % 100000 == 0)) begin
 | 
					                force dut.hart.ifu.InstrRawD = 32'b0010011;
 | 
				
			||||||
            $display("loaded %0d instructions", instrs);
 | 
					                #7;
 | 
				
			||||||
          end
 | 
					                release dut.hart.ifu.InstrRawD;
 | 
				
			||||||
          instrs += 1;
 | 
					                $display("warning: NOPing out %s at PC=%0x, instr %0d, time %0t", PCtext, dut.hart.ifu.PCD, instrs, $time);
 | 
				
			||||||
          // are we at a branch/jump?
 | 
					                warningCount += 1;
 | 
				
			||||||
          casex (lastCheckInstrF[31:0])
 | 
					                forcedInstr = 1;
 | 
				
			||||||
            32'b00000000001000000000000001110011, // URET
 | 
					              end
 | 
				
			||||||
            32'b00010000001000000000000001110011, // SRET
 | 
					              else begin
 | 
				
			||||||
            32'b00110000001000000000000001110011, // MRET
 | 
					                forcedInstr = 0;
 | 
				
			||||||
            32'bXXXXXXXXXXXXXXXXXXXXXXXXX1101111, // JAL
 | 
					              end
 | 
				
			||||||
            32'bXXXXXXXXXXXXXXXXXXXXXXXXX1100111, // JALR
 | 
					            end
 | 
				
			||||||
            32'bXXXXXXXXXXXXXXXXXXXXXXXXX1100011, // B
 | 
					            // then expected PC value
 | 
				
			||||||
            32'bXXXXXXXXXXXXXXXX110XXXXXXXXXXX01, // C.BEQZ
 | 
					            scan_file_PC = $fscanf(data_file_PC, "%x\n", pcExpected);
 | 
				
			||||||
            32'bXXXXXXXXXXXXXXXX111XXXXXXXXXXX01, // C.BNEZ
 | 
					            if (instrs <= 10 || (instrs <= 100 && instrs % 10 == 0) ||
 | 
				
			||||||
            32'bXXXXXXXXXXXXXXXX101XXXXXXXXXXX01: // C.J
 | 
					               (instrs <= 1000 && instrs % 100 == 0) || (instrs <= 10000 && instrs % 1000 == 0) ||
 | 
				
			||||||
              speculative = 1;
 | 
					               (instrs <= 100000 && instrs % 10000 == 0) || (instrs <= 1000000 && instrs % 100000 == 0)) begin
 | 
				
			||||||
            32'bXXXXXXXXXXXXXXXX1001000000000010: // C.EBREAK:
 | 
					              $display("loaded %0d instructions", instrs);
 | 
				
			||||||
              speculative = 0; // tbh don't really know what should happen here
 | 
					            end
 | 
				
			||||||
            32'bXXXXXXXXXXXXXXXX1000XXXXX0000010, // C.JR
 | 
					            instrs += 1;
 | 
				
			||||||
            32'bXXXXXXXXXXXXXXXX1001XXXXX0000010: // C.JALR //this is RV64 only so no C.JAL
 | 
					            // are we at a branch/jump?
 | 
				
			||||||
              speculative = 1;
 | 
					            casex (lastCheckInstrD[31:0])
 | 
				
			||||||
            default:
 | 
					              32'b00000000001000000000000001110011, // URET
 | 
				
			||||||
              speculative = 0;
 | 
					              32'b00010000001000000000000001110011, // SRET
 | 
				
			||||||
          endcase
 | 
					              32'b00110000001000000000000001110011, // MRET
 | 
				
			||||||
 | 
					              32'bXXXXXXXXXXXXXXXXXXXXXXXXX1101111, // JAL
 | 
				
			||||||
 | 
					              32'bXXXXXXXXXXXXXXXXXXXXXXXXX1100111, // JALR
 | 
				
			||||||
 | 
					              32'bXXXXXXXXXXXXXXXXXXXXXXXXX1100011, // B
 | 
				
			||||||
 | 
					              32'bXXXXXXXXXXXXXXXX110XXXXXXXXXXX01, // C.BEQZ
 | 
				
			||||||
 | 
					              32'bXXXXXXXXXXXXXXXX111XXXXXXXXXXX01, // C.BNEZ
 | 
				
			||||||
 | 
					              32'bXXXXXXXXXXXXXXXX101XXXXXXXXXXX01: // C.J
 | 
				
			||||||
 | 
					                speculative = 1;
 | 
				
			||||||
 | 
					              32'bXXXXXXXXXXXXXXXX1001000000000010: // C.EBREAK:
 | 
				
			||||||
 | 
					                speculative = 0; // tbh don't really know what should happen here
 | 
				
			||||||
 | 
					              32'bXXXXXXXXXXXXXXXX1000XXXXX0000010, // C.JR
 | 
				
			||||||
 | 
					              32'bXXXXXXXXXXXXXXXX1001XXXXX0000010: // C.JALR //this is RV64 only so no C.JAL
 | 
				
			||||||
 | 
					                speculative = 1;
 | 
				
			||||||
 | 
					              default:
 | 
				
			||||||
 | 
					                speculative = 0;
 | 
				
			||||||
 | 
					            endcase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          //check things!
 | 
					            //check things!
 | 
				
			||||||
          if ((~speculative) && (~equal(dut.PCF,pcExpected,3))) begin
 | 
					            if ((~speculative) && (~equal(dut.hart.ifu.PCD,pcExpected,3))) begin
 | 
				
			||||||
            $display("%0t ps, instr %0d: PC does not equal PC expected: %x, %x", $time, instrs, dut.PCF, pcExpected);
 | 
					              $display("%0t ps, instr %0d: PC does not equal PC expected: %x, %x", $time, instrs, dut.hart.ifu.PCD, pcExpected);
 | 
				
			||||||
            `ERROR
 | 
					              `ERROR
 | 
				
			||||||
          end
 | 
					            end
 | 
				
			||||||
          InstrMask = CheckInstrF[1:0] == 2'b11 ? 32'hFFFFFFFF : 32'h0000FFFF;
 | 
					            InstrMask = CheckInstrD[1:0] == 2'b11 ? 32'hFFFFFFFF : 32'h0000FFFF;
 | 
				
			||||||
          if ((~forcedInstr) && (~speculative) && ((InstrMask & dut.hart.ifu.InstrF) !== (InstrMask & CheckInstrF))) begin
 | 
					            if ((~forcedInstr) && (~speculative) && ((InstrMask & dut.hart.ifu.InstrRawD) !== (InstrMask & CheckInstrD))) begin
 | 
				
			||||||
            $display("%0t ps, instr %0d: InstrF does not equal CheckInstrF: %x, %x, PC: %x", $time, instrs, dut.hart.ifu.InstrF, CheckInstrF, dut.PCF);
 | 
					              $display("%0t ps, instr %0d: InstrD does not equal CheckInstrD: %x, %x, PC: %x", $time, instrs, dut.hart.ifu.InstrRawD, CheckInstrD, dut.hart.ifu.PCD);
 | 
				
			||||||
            `ERROR
 | 
					              `ERROR
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
          end
 | 
					          end
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
 | 
					        lastPCD = dut.hart.ifu.PCD;
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
      lastPCF = dut.PCF;
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -485,7 +485,7 @@ module testbench_busybear();
 | 
				
			|||||||
  string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName;
 | 
					  string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName;
 | 
				
			||||||
  logic [31:0] InstrW;
 | 
					  logic [31:0] InstrW;
 | 
				
			||||||
  flopenr  #(32)   InstrWReg(clk, reset, ~dut.hart.ieu.dp.StallW, dut.hart.ifu.InstrM, InstrW);
 | 
					  flopenr  #(32)   InstrWReg(clk, reset, ~dut.hart.ieu.dp.StallW, dut.hart.ifu.InstrM, InstrW);
 | 
				
			||||||
  instrNameDecTB dec(dut.hart.ifu.InstrF, InstrFName);
 | 
					  instrNameDecTB dec(dut.hart.ifu.ic.InstrF, InstrFName);
 | 
				
			||||||
  instrTrackerTB it(clk, reset, dut.hart.ieu.dp.FlushE,
 | 
					  instrTrackerTB it(clk, reset, dut.hart.ieu.dp.FlushE,
 | 
				
			||||||
                dut.hart.ifu.InstrD, dut.hart.ifu.InstrE,
 | 
					                dut.hart.ifu.InstrD, dut.hart.ifu.InstrE,
 | 
				
			||||||
                dut.hart.ifu.InstrM,  InstrW,
 | 
					                dut.hart.ifu.InstrM,  InstrW,
 | 
				
			||||||
 | 
				
			|||||||
@ -65,7 +65,6 @@ module testbench();
 | 
				
			|||||||
//                    "rv64m/I-REMW-01", "3000"
 | 
					//                    "rv64m/I-REMW-01", "3000"
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  string tests64ic[] = '{
 | 
					  string tests64ic[] = '{
 | 
				
			||||||
 | 
					 | 
				
			||||||
                     "rv64ic/I-C-ADD-01", "3000",
 | 
					                     "rv64ic/I-C-ADD-01", "3000",
 | 
				
			||||||
                     "rv64ic/I-C-ADDI-01", "3000",
 | 
					                     "rv64ic/I-C-ADDI-01", "3000",
 | 
				
			||||||
                     "rv64ic/I-C-ADDIW-01", "3000",
 | 
					                     "rv64ic/I-C-ADDIW-01", "3000",
 | 
				
			||||||
@ -381,9 +380,9 @@ string tests32i[] = {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  // Track names of instructions
 | 
					  // Track names of instructions
 | 
				
			||||||
  instrTrackerTB it(clk, reset, dut.hart.ieu.dp.FlushE,
 | 
					  instrTrackerTB it(clk, reset, dut.hart.ieu.dp.FlushE,
 | 
				
			||||||
                dut.hart.ifu.InstrF, dut.hart.ifu.InstrD, dut.hart.ifu.InstrE,
 | 
					                dut.hart.ifu.ic.InstrF, dut.hart.ifu.InstrD, dut.hart.ifu.InstrE,
 | 
				
			||||||
                dut.hart.ifu.InstrM,  InstrW,
 | 
					                dut.hart.ifu.InstrM, InstrW, InstrFName, InstrDName,
 | 
				
			||||||
                InstrFName, InstrDName, InstrEName, InstrMName, InstrWName);
 | 
					                InstrEName, InstrMName, InstrWName);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // initialize tests
 | 
					  // initialize tests
 | 
				
			||||||
  initial
 | 
					  initial
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user