From b0f4d8e8d4ba748e4ace472372bc190e3743c9ca Mon Sep 17 00:00:00 2001 From: Jarred Allen Date: Thu, 4 Mar 2021 16:46:43 -0500 Subject: [PATCH 01/41] Remove rd2, working for non-compressed --- wally-pipelined/regression/wally-pipelined.do | 6 +- wally-pipelined/src/ifu/icache.sv | 90 +++++++++++++++++++ wally-pipelined/src/ifu/ifu.sv | 35 +++----- .../testbench/testbench-imperas.sv | 2 +- 4 files changed, 109 insertions(+), 24 deletions(-) create mode 100644 wally-pipelined/src/ifu/icache.sv diff --git a/wally-pipelined/regression/wally-pipelined.do b/wally-pipelined/regression/wally-pipelined.do index c90512741..cf9a39cd9 100644 --- a/wally-pipelined/regression/wally-pipelined.do +++ b/wally-pipelined/regression/wally-pipelined.do @@ -60,11 +60,13 @@ add wave /testbench/dut/hart/FlushW add wave -divider 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/InstrD 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 -hex /testbench/dut/hart/ifu/ic/MisalignedHalfInstrD add wave -divider add wave -hex /testbench/dut/hart/ifu/PCE add wave -hex /testbench/dut/hart/ifu/InstrE diff --git a/wally-pipelined/src/ifu/icache.sv b/wally-pipelined/src/ifu/icache.sv new file mode 100644 index 000000000..df0de4d30 --- /dev/null +++ b/wally-pipelined/src/ifu/icache.sv @@ -0,0 +1,90 @@ +/////////////////////////////////////////// +// icache.sv +// +// Written: jaallen@g.hmc.edu 2021-03-02 +// Modified: +// +// Purpose: Cache instructions for the ifu so it can access memory less often +// +// 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( + input logic clk, reset, + input logic StallF, StallD, + input logic FlushD, + // Fetch + input logic [`XLEN-1:0] PCPF, + input logic [`XLEN-1:0] InstrInF, + output logic [`XLEN-1:0] InstrPAdrF, + output logic InstrReadF, + // Decode + output logic [31:0] InstrRawD +); + + logic DelayF, DelaySideF, FlushDLastCycle; + logic [1:0] InstrDMuxChoice; + logic [15:0] MisalignedHalfInstrF, MisalignedHalfInstrD; + logic [31:0] InstrF, AlignedInstrD; + logic [31:0] nop = 32'h00000013; // instruction for NOP + + flopr #(1) flushDLastCycleFlop(clk, reset, FlushD | (FlushDLastCycle & StallF), FlushDLastCycle); + flopenr #(1) delayStateFlop(clk, reset, ~StallF, (DelayF & ~DelaySideF) ? 1'b1 : 1'b0 , DelaySideF); + flopenr #(16) halfInstrFlop(clk, reset, DelayF, MisalignedHalfInstrF, MisalignedHalfInstrD); + + flopenr #(32) instrFlop(clk, reset, ~StallF, InstrF, AlignedInstrD); + + // 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 ? {PCPF[31:2]+1, 2'b00} : {PCPF[31:2], 2'b00}) : PCPF; + end else begin + assign InstrPAdrF = PCPF[2] ? (PCPF[1] ? (DelaySideF ? {PCPF[63:3]+1, 3'b000} : {PCPF[63:3], 3'b000}) : {PCPF[63:3], 3'b000}) : {PCPF[63:3], 3'b000}; + end + endgenerate + // For now, we always read since the cache doesn't actually cache + assign InstrReadF = 1; + + // 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] ? 32'b0 : InstrInF; + assign DelayF = PCPF[1]; + assign MisalignedHalfInstrF = InstrInF[31:16]; + end else begin + assign InstrF = PCPF[2] ? (PCPF[1] ? 64'b0 : InstrInF[63:32]) : (PCPF[1] ? InstrInF[47:16] : InstrInF[31:0]); + assign DelayF = PCPF[1] && PCPF[2]; + assign MisalignedHalfInstrF = InstrInF[63:48]; + end + endgenerate + + // 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 + assign InstrDMuxChoice = FlushDLastCycle ? 2'b10 : (DelayF ? (DelaySideF ? 2'b01 : 2'b10) : 2'b00); + mux3 #(32) instrDMux (AlignedInstrD, {InstrInF[15:0], MisalignedHalfInstrD}, nop, InstrDMuxChoice, InstrRawD); +endmodule diff --git a/wally-pipelined/src/ifu/ifu.sv b/wally-pipelined/src/ifu/ifu.sv index 88e4f0bef..abfb37c88 100644 --- a/wally-pipelined/src/ifu/ifu.sv +++ b/wally-pipelined/src/ifu/ifu.sv @@ -2,7 +2,7 @@ // ifu.sv // // Written: David_Harris@hmc.edu 9 January 2021 -// Modified: +// Modified: // // Purpose: Instrunction Fetch Unit // PC, branch prediction, instruction cache @@ -51,25 +51,24 @@ module ifu ( input logic IllegalBaseInstrFaultD, output logic IllegalIEUInstrFaultD, output logic InstrMisalignedFaultM, - output logic [`XLEN-1:0] InstrMisalignedAdrM, // TLB management //input logic [`XLEN-1:0] PageTableEntryF, //input logic ITLBWriteF, ITLBFlushF, // *** satp value will come from CSRs // input logic [`XLEN-1:0] SATP, output logic ITLBMissF, ITLBHitF, - // bogus - input logic [15:0] rd2 + output logic [`XLEN-1:0] InstrMisalignedAdrM ); logic [`XLEN-1:0] UnalignedPCNextF, PCNextF; logic misaligned, BranchMisalignedFaultE, BranchMisalignedFaultM, TrapMisalignedFaultM; logic PrivilegedChangePCM; logic IllegalCompInstrD; - logic [`XLEN-1:0] PCPlusUpperF, PCPlus2or4F, PCD, PCW, PCLinkD, PCLinkE, PCLinkM; + logic [`XLEN-1:0] PCPlusUpperF, PCPlus2or4F, PCD, PCW, PCLinkD, PCLinkE, PCLinkM, PCPF; logic CompressedF; - logic [31:0] InstrF, InstrRawD, InstrE, InstrW; + logic [31:0] InstrRawD, InstrE, InstrW; logic [31:0] nop = 32'h00000013; // instruction for NOP + logic [`XLEN-1:0] ITLBInstrPAdrF, ICacheInstrPAdrF; // *** temporary hack until we can figure out how to get actual satp value // from priv unit -- Thomas F @@ -79,23 +78,28 @@ module ifu ( logic ITLBFlushF = '0; logic ITLBWriteF = '0; tlb #(3) itlb(clk, reset, SATP, PCF, PageTableEntryF, ITLBWriteF, ITLBFlushF, - InstrPAdrF, ITLBMissF, ITLBHitF); + ITLBInstrPAdrF, ITLBMissF, ITLBHitF); // *** put memory interface on here, InstrF becomes output //assign InstrPAdrF = PCF; // *** no MMU //assign InstrReadF = ~StallD; // *** & ICacheMissF; add later - assign InstrReadF = 1; // *** & ICacheMissF; add later + // assign InstrReadF = 1; // *** & ICacheMissF; add later + + // jarred 2021-03-04 Add instrution cache block to remove rd2 + assign PCPF = PCF; // Temporary workaround until iTLB is live + icache ic(clk, reset, StallF, StallD, FlushD, PCPF, InstrInF, ICacheInstrPAdrF, InstrReadF, InstrRawD); + // Prioritize the iTLB for reads if it wants one + mux2 #(`XLEN) instrPAdrMux(ICacheInstrPAdrF, ITLBInstrPAdrF, ITLBMissF, InstrPAdrF); assign PrivilegedChangePCM = RetM | TrapM; - mux3 #(`XLEN) pcmux(PCPlus2or4F, PCTargetE, PrivilegedNextPCM, {PrivilegedChangePCM, PCSrcE}, UnalignedPCNextF); 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); // pcadder // 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 CompressedF = 0; // is it a 16-bit compressed instruction? TODO Fix this assign PCPlusUpperF = PCF[`XLEN-1:2] + 1; // add 4 to PC // choose PC+2 or PC+4 @@ -105,18 +109,7 @@ module ifu ( else PCPlus2or4F = {PCF[`XLEN-1:2], 2'b10}; 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 - flopenl #(32) InstrDReg(clk, reset, ~StallD, (FlushD ? nop : InstrF), nop, InstrRawD); flopenrc #(`XLEN) PCDReg(clk, reset, FlushD, ~StallD, PCF, PCD); // expand 16-bit compressed instructions to 32 bits diff --git a/wally-pipelined/testbench/testbench-imperas.sv b/wally-pipelined/testbench/testbench-imperas.sv index 49a5263d6..7498de76d 100644 --- a/wally-pipelined/testbench/testbench-imperas.sv +++ b/wally-pipelined/testbench/testbench-imperas.sv @@ -347,7 +347,7 @@ string tests32i[] = { // Track names of instructions 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, dut.hart.ifu.InstrW, InstrFName, InstrDName, InstrEName, InstrMName, InstrWName); From 5da98b53815c232c0c92ee0223adaf6999bc53a4 Mon Sep 17 00:00:00 2001 From: Jarred Allen Date: Thu, 4 Mar 2021 18:30:26 -0500 Subject: [PATCH 02/41] Partial progress towards compressed instructions --- wally-pipelined/src/hazard/hazard.sv | 2 +- wally-pipelined/src/ifu/icache.sv | 13 ++++++++--- wally-pipelined/src/ifu/ifu.sv | 23 +++++++++---------- .../src/wally/wallypipelinedhart.sv | 3 +++ .../testbench/testbench-imperas.sv | 2 +- 5 files changed, 26 insertions(+), 17 deletions(-) diff --git a/wally-pipelined/src/hazard/hazard.sv b/wally-pipelined/src/hazard/hazard.sv index 43fc1ad96..3b54139c3 100644 --- a/wally-pipelined/src/hazard/hazard.sv +++ b/wally-pipelined/src/hazard/hazard.sv @@ -29,7 +29,7 @@ module hazard( // Detect hazards input logic PCSrcE, CSRWritePendingDEM, RetM, TrapM, input logic LoadStallD, MulDivStallD, CSRRdStallD, - input logic InstrStall, DataStall, + input logic InstrStall, DataStall, ICacheStallF, // Stall & flush outputs output logic StallF, StallD, StallE, StallM, StallW, output logic FlushD, FlushE, FlushM, FlushW diff --git a/wally-pipelined/src/ifu/icache.sv b/wally-pipelined/src/ifu/icache.sv index df0de4d30..b07e64056 100644 --- a/wally-pipelined/src/ifu/icache.sv +++ b/wally-pipelined/src/ifu/icache.sv @@ -34,6 +34,8 @@ module icache( input logic [`XLEN-1:0] InstrInF, output logic [`XLEN-1:0] InstrPAdrF, output logic InstrReadF, + output logic CompressedF, + output logic ICacheStallF, // Decode output logic [31:0] InstrRawD ); @@ -46,7 +48,7 @@ module icache( flopr #(1) flushDLastCycleFlop(clk, reset, FlushD | (FlushDLastCycle & StallF), FlushDLastCycle); flopenr #(1) delayStateFlop(clk, reset, ~StallF, (DelayF & ~DelaySideF) ? 1'b1 : 1'b0 , DelaySideF); - flopenr #(16) halfInstrFlop(clk, reset, DelayF, MisalignedHalfInstrF, MisalignedHalfInstrD); + flopenr #(16) halfInstrFlop(clk, reset, DelayF & ~StallF, MisalignedHalfInstrF, MisalignedHalfInstrD); flopenr #(32) instrFlop(clk, reset, ~StallF, InstrF, AlignedInstrD); @@ -69,15 +71,20 @@ module icache( // machinery to swizzle bits. generate if (`XLEN == 32) begin - assign InstrF = PCPF[1] ? 32'b0 : InstrInF; + assign InstrF = PCPF[1] ? {16'b0, InstrInF[31:16]} : InstrInF; assign DelayF = PCPF[1]; assign MisalignedHalfInstrF = InstrInF[31:16]; end else begin - assign InstrF = PCPF[2] ? (PCPF[1] ? 64'b0 : InstrInF[63:32]) : (PCPF[1] ? InstrInF[47:16] : InstrInF[31:0]); + assign InstrF = PCPF[2] ? (PCPF[1] ? {16'b0, InstrInF[63:48]} : InstrInF[63:32]) : (PCPF[1] ? InstrInF[47:16] : InstrInF[31:0]); assign DelayF = PCPF[1] && PCPF[2]; assign MisalignedHalfInstrF = InstrInF[63:48]; end endgenerate + assign ICacheStallF = DelayF & ~DelaySideF; + + // Detect if the instruction is compressed + // TODO Low-hanging optimization, don't delay if compressed + assign CompressedF = DelaySideF ? (MisalignedHalfInstrD[1:0] != 2'b11) : (InstrF[1:0] != 2'b11); // Pick the correct output, depending on whether we have to assemble this // instruction from two reads or not. diff --git a/wally-pipelined/src/ifu/ifu.sv b/wally-pipelined/src/ifu/ifu.sv index abfb37c88..e48078fea 100644 --- a/wally-pipelined/src/ifu/ifu.sv +++ b/wally-pipelined/src/ifu/ifu.sv @@ -35,6 +35,7 @@ module ifu ( output logic [`XLEN-1:0] PCF, output logic [`XLEN-1:0] InstrPAdrF, output logic InstrReadF, + output logic ICacheStallF, // Decode // Execute input logic PCSrcE, @@ -51,23 +52,23 @@ module ifu ( input logic IllegalBaseInstrFaultD, output logic IllegalIEUInstrFaultD, output logic InstrMisalignedFaultM, + output logic [`XLEN-1:0] InstrMisalignedAdrM, // TLB management //input logic [`XLEN-1:0] PageTableEntryF, //input logic ITLBWriteF, ITLBFlushF, // *** satp value will come from CSRs // input logic [`XLEN-1:0] SATP, - output logic ITLBMissF, ITLBHitF, - output logic [`XLEN-1:0] InstrMisalignedAdrM + output logic ITLBMissF, ITLBHitF ); logic [`XLEN-1:0] UnalignedPCNextF, PCNextF; - logic misaligned, BranchMisalignedFaultE, BranchMisalignedFaultM, TrapMisalignedFaultM; - logic PrivilegedChangePCM; - logic IllegalCompInstrD; + logic misaligned, BranchMisalignedFaultE, BranchMisalignedFaultM, TrapMisalignedFaultM; + logic PrivilegedChangePCM; + logic IllegalCompInstrD; logic [`XLEN-1:0] PCPlusUpperF, PCPlus2or4F, PCD, PCW, PCLinkD, PCLinkE, PCLinkM, PCPF; - logic CompressedF; - logic [31:0] InstrRawD, InstrE, InstrW; - logic [31:0] nop = 32'h00000013; // instruction for NOP + logic CompressedF; + logic [31:0] InstrRawD, InstrE, InstrW; + logic [31:0] nop = 32'h00000013; // instruction for NOP logic [`XLEN-1:0] ITLBInstrPAdrF, ICacheInstrPAdrF; // *** temporary hack until we can figure out how to get actual satp value @@ -87,7 +88,7 @@ module ifu ( // jarred 2021-03-04 Add instrution cache block to remove rd2 assign PCPF = PCF; // Temporary workaround until iTLB is live - icache ic(clk, reset, StallF, StallD, FlushD, PCPF, InstrInF, ICacheInstrPAdrF, InstrReadF, InstrRawD); + icache ic(clk, reset, StallF, StallD, FlushD, PCPF, InstrInF, ICacheInstrPAdrF, InstrReadF, CompressedF, ICacheStallF, InstrRawD); // Prioritize the iTLB for reads if it wants one mux2 #(`XLEN) instrPAdrMux(ICacheInstrPAdrF, ITLBInstrPAdrF, ITLBMissF, InstrPAdrF); @@ -95,13 +96,11 @@ module ifu ( mux3 #(`XLEN) pcmux(PCPlus2or4F, PCTargetE, PrivilegedNextPCM, {PrivilegedChangePCM, PCSrcE}, UnalignedPCNextF); 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); // pcadder // add 2 or 4 to the PC, based on whether the instruction is 16 bits or 32 - assign CompressedF = 0; // is it a 16-bit compressed instruction? TODO Fix this assign PCPlusUpperF = PCF[`XLEN-1:2] + 1; // add 4 to PC - // choose PC+2 or PC+4 always_comb if (CompressedF) // add 2 diff --git a/wally-pipelined/src/wally/wallypipelinedhart.sv b/wally-pipelined/src/wally/wallypipelinedhart.sv index ded4df3d8..4f34fe2d7 100644 --- a/wally-pipelined/src/wally/wallypipelinedhart.sv +++ b/wally-pipelined/src/wally/wallypipelinedhart.sv @@ -91,6 +91,9 @@ module wallypipelinedhart ( logic ITLBMissF, ITLBHitF; logic DTLBMissM, DTLBHitM; + // ICache stalls + logic ICacheStallF; + // bus interface to dmem logic MemReadM, MemWriteM; logic [2:0] Funct3M; diff --git a/wally-pipelined/testbench/testbench-imperas.sv b/wally-pipelined/testbench/testbench-imperas.sv index 7498de76d..8947482ea 100644 --- a/wally-pipelined/testbench/testbench-imperas.sv +++ b/wally-pipelined/testbench/testbench-imperas.sv @@ -322,7 +322,7 @@ string tests32i[] = { initial if (`XLEN == 64) begin // RV64 tests = {tests64i}; - if (`C_SUPPORTED % 2 == 1) tests = {tests, tests64ic}; + if (`C_SUPPORTED % 2 == 1) tests = {tests64ic, tests}; else tests = {tests, tests64iNOc}; if (`M_SUPPORTED % 2 == 1) tests = {tests, tests64m}; end else begin // RV32 From 81b29a3891a9404b457ac403ef33ef11f57315d9 Mon Sep 17 00:00:00 2001 From: Jarred Allen Date: Tue, 9 Mar 2021 21:16:07 -0500 Subject: [PATCH 03/41] More progress --- wally-pipelined/src/ifu/icache.sv | 53 +++++++++++++------ .../testbench/testbench-imperas.sv | 3 +- 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/wally-pipelined/src/ifu/icache.sv b/wally-pipelined/src/ifu/icache.sv index b07e64056..d8083bb6c 100644 --- a/wally-pipelined/src/ifu/icache.sv +++ b/wally-pipelined/src/ifu/icache.sv @@ -40,18 +40,26 @@ module icache( output logic [31:0] InstrRawD ); - logic DelayF, DelaySideF, FlushDLastCycle; - logic [1:0] InstrDMuxChoice; - logic [15:0] MisalignedHalfInstrF, MisalignedHalfInstrD; - logic [31:0] InstrF, AlignedInstrD; - logic [31:0] nop = 32'h00000013; // instruction for NOP + logic DelayF, DelaySideF, FlushDLastCycle; + logic [1:0] InstrDMuxChoice; + logic [15:0] MisalignedHalfInstrF, MisalignedHalfInstrD; + logic [31:0] InstrF, AlignedInstrD; + logic [31:0] nop = 32'h00000013; // instruction for NOP + logic LastReadDataValidF; + logic [`XLEN-1:0] LastReadDataF, LastReadAdrF, InDataF; flopr #(1) flushDLastCycleFlop(clk, reset, FlushD | (FlushDLastCycle & StallF), FlushDLastCycle); flopenr #(1) delayStateFlop(clk, reset, ~StallF, (DelayF & ~DelaySideF) ? 1'b1 : 1'b0 , DelaySideF); 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 @@ -64,34 +72,47 @@ module icache( end endgenerate // For now, we always read since the cache doesn't actually cache - assign InstrReadF = 1; + + 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, InstrInF[31:16]} : InstrInF; + assign InstrF = PCPF[1] ? {16'b0, InDataF[31:16]} : InDataF; assign DelayF = PCPF[1]; - assign MisalignedHalfInstrF = InstrInF[31:16]; + assign MisalignedHalfInstrF = InDataF[31:16]; end else begin - assign InstrF = PCPF[2] ? (PCPF[1] ? {16'b0, InstrInF[63:48]} : InstrInF[63:32]) : (PCPF[1] ? InstrInF[47:16] : InstrInF[31:0]); + 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 = InstrInF[63:48]; + assign MisalignedHalfInstrF = InDataF[63:48]; end endgenerate - assign ICacheStallF = DelayF & ~DelaySideF; + assign ICacheStallF = 0; //DelayF & ~DelaySideF; // Detect if the instruction is compressed - // TODO Low-hanging optimization, don't delay if compressed - assign CompressedF = DelaySideF ? (MisalignedHalfInstrD[1:0] != 2'b11) : (InstrF[1:0] != 2'b11); + // TODO Low-hanging optimization, don't delay if getting a compressed instruction + assign CompressedF = (DelaySideF & DelayF) ? (MisalignedHalfInstrD[1:0] != 2'b11) : (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 - assign InstrDMuxChoice = FlushDLastCycle ? 2'b10 : (DelayF ? (DelaySideF ? 2'b01 : 2'b10) : 2'b00); - mux3 #(32) instrDMux (AlignedInstrD, {InstrInF[15:0], MisalignedHalfInstrD}, nop, InstrDMuxChoice, InstrRawD); + always_comb if (DelayF & (MisalignedHalfInstrF[1:0] != 2'b11)) begin + assign InstrDMuxChoice = 2'b11; + end else if (FlushDLastCycle) begin + assign InstrDMuxChoice = 2'b10; + end else begin + assign InstrDMuxChoice = {1'b0, DelaySideF}; + end + mux4 #(32) instrDMux (AlignedInstrD, {InstrInF[15:0], MisalignedHalfInstrD}, nop, {16'b0, MisalignedHalfInstrD}, InstrDMuxChoice, InstrRawD); endmodule diff --git a/wally-pipelined/testbench/testbench-imperas.sv b/wally-pipelined/testbench/testbench-imperas.sv index 8947482ea..334e75e24 100644 --- a/wally-pipelined/testbench/testbench-imperas.sv +++ b/wally-pipelined/testbench/testbench-imperas.sv @@ -53,14 +53,13 @@ module testbench(); // "rv64m/I-REMW-01", "3000" }; string tests64ic[] = '{ - + "rv64ic/I-C-BEQZ-01", "3000", "rv64ic/I-C-ADD-01", "3000", "rv64ic/I-C-ADDI-01", "3000", "rv64ic/I-C-ADDIW-01", "3000", "rv64ic/I-C-ADDW-01", "3000", "rv64ic/I-C-AND-01", "3000", "rv64ic/I-C-ANDI-01", "3000", - "rv64ic/I-C-BEQZ-01", "3000", "rv64ic/I-C-BNEZ-01", "3000", "rv64ic/I-C-EBREAK-01", "2000", "rv64ic/I-C-J-01", "3000", From ff48a9e992903ceaa536fe3d0bab7025f991ec9a Mon Sep 17 00:00:00 2001 From: Jarred Allen Date: Wed, 10 Mar 2021 22:58:41 -0500 Subject: [PATCH 04/41] Return testbench to normal --- wally-pipelined/testbench/testbench-imperas.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wally-pipelined/testbench/testbench-imperas.sv b/wally-pipelined/testbench/testbench-imperas.sv index 9c064f1a4..b59d54534 100644 --- a/wally-pipelined/testbench/testbench-imperas.sv +++ b/wally-pipelined/testbench/testbench-imperas.sv @@ -56,13 +56,13 @@ module testbench(); // "rv64m/I-REMW-01", "3000" }; string tests64ic[] = '{ - "rv64ic/I-C-BEQZ-01", "3000", "rv64ic/I-C-ADD-01", "3000", "rv64ic/I-C-ADDI-01", "3000", "rv64ic/I-C-ADDIW-01", "3000", "rv64ic/I-C-ADDW-01", "3000", "rv64ic/I-C-AND-01", "3000", "rv64ic/I-C-ANDI-01", "3000", + "rv64ic/I-C-BEQZ-01", "3000", "rv64ic/I-C-BNEZ-01", "3000", "rv64ic/I-C-EBREAK-01", "2000", "rv64ic/I-C-J-01", "3000", @@ -327,7 +327,7 @@ string tests32i[] = { if (`C_SUPPORTED) tests = {tests64ic, tests}; else tests = {tests, tests64iNOc}; if (`M_SUPPORTED) tests = {tests, tests64m}; - if (`A_SUPPORTED) tests = {tests64a, tests}; + if (`A_SUPPORTED) tests = {tests, tests64a}; // tests = {tests64a, tests}; end else begin // RV32 tests = {tests32i}; From b30ea396b86e926aabc027941ce06dc02c556e7a Mon Sep 17 00:00:00 2001 From: bbracker Date: Sat, 13 Mar 2021 07:03:33 -0500 Subject: [PATCH 05/41] slightly smarter dtim HREADY --- wally-pipelined/src/uncore/dtim.sv | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/wally-pipelined/src/uncore/dtim.sv b/wally-pipelined/src/uncore/dtim.sv index 42ae7fbcc..3634b022e 100644 --- a/wally-pipelined/src/uncore/dtim.sv +++ b/wally-pipelined/src/uncore/dtim.sv @@ -40,6 +40,8 @@ module dtim #(parameter BASE=0, RANGE = 65535) ( logic [`XLEN-1:0] HREADTim0; // logic [`XLEN-1:0] write; + logic [31:0] HADDRd; + logic newAdr; logic [15:0] entry; logic memread, memwrite; logic [3:0] busycount; @@ -48,14 +50,17 @@ module dtim #(parameter BASE=0, RANGE = 65535) ( memread <= HSELTim & ~ HWRITE; memwrite <= HSELTim & HWRITE; A <= HADDR; + HADDRd <= HADDR; end + assign newAdr = HADDR!=HADDRd; + // busy FSM to extend READY signal always_ff @(posedge HCLK, negedge HRESETn) if (~HRESETn) begin HREADYTim <= 1; end else begin - if (HREADYTim & HSELTim) begin + if ((HREADYTim | newAdr) & HSELTim) begin busycount <= 0; HREADYTim <= #1 0; end else if (~HREADYTim) begin From c2f2caa3f628e8c2e0a6cd164b11a339645f0b95 Mon Sep 17 00:00:00 2001 From: Jarred Allen Date: Sun, 14 Mar 2021 14:46:21 -0400 Subject: [PATCH 06/41] Get non-jump case working --- wally-pipelined/regression/wally-pipelined.do | 3 +++ wally-pipelined/src/ifu/icache.sv | 9 +++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/wally-pipelined/regression/wally-pipelined.do b/wally-pipelined/regression/wally-pipelined.do index f982d302c..ddcd6c0d8 100644 --- a/wally-pipelined/regression/wally-pipelined.do +++ b/wally-pipelined/regression/wally-pipelined.do @@ -74,6 +74,9 @@ 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 /testbench/dut/hart/ifu/ic/DelaySideD add wave -hex /testbench/dut/hart/ifu/ic/MisalignedHalfInstrD add wave -divider add wave -hex /testbench/dut/hart/ifu/PCE diff --git a/wally-pipelined/src/ifu/icache.sv b/wally-pipelined/src/ifu/icache.sv index d8083bb6c..67a52800a 100644 --- a/wally-pipelined/src/ifu/icache.sv +++ b/wally-pipelined/src/ifu/icache.sv @@ -40,7 +40,7 @@ module icache( output logic [31:0] InstrRawD ); - logic DelayF, DelaySideF, FlushDLastCycle; + logic DelayF, DelaySideF, FlushDLastCycle, DelayD, DelaySideD; logic [1:0] InstrDMuxChoice; logic [15:0] MisalignedHalfInstrF, MisalignedHalfInstrD; logic [31:0] InstrF, AlignedInstrD; @@ -49,7 +49,9 @@ module icache( logic [`XLEN-1:0] LastReadDataF, LastReadAdrF, InDataF; flopr #(1) flushDLastCycleFlop(clk, reset, FlushD | (FlushDLastCycle & StallF), FlushDLastCycle); - flopenr #(1) delayStateFlop(clk, reset, ~StallF, (DelayF & ~DelaySideF) ? 1'b1 : 1'b0 , DelaySideF); + flopenr #(1) delayDFlop(clk, reset, ~StallF, DelayF, DelayD); + flopenr #(1) delaySideDFlop(clk, reset, ~StallF, DelaySideF, DelaySideD); + flopenr #(1) delayStateFlop(clk, reset, ~StallF, DelayF & ~DelaySideF, DelaySideF); 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 @@ -99,7 +101,6 @@ module icache( assign ICacheStallF = 0; //DelayF & ~DelaySideF; // Detect if the instruction is compressed - // TODO Low-hanging optimization, don't delay if getting a compressed instruction assign CompressedF = (DelaySideF & DelayF) ? (MisalignedHalfInstrD[1:0] != 2'b11) : (InstrF[1:0] != 2'b11); // Pick the correct output, depending on whether we have to assemble this @@ -107,7 +108,7 @@ module icache( // 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 (DelayF & (MisalignedHalfInstrF[1:0] != 2'b11)) begin + always_comb if (DelayD & (MisalignedHalfInstrD[1:0] != 2'b11)) begin assign InstrDMuxChoice = 2'b11; end else if (FlushDLastCycle) begin assign InstrDMuxChoice = 2'b10; From 5b174adc2a41a42d6b58cafb4fcecc00cdfc8d01 Mon Sep 17 00:00:00 2001 From: Jarred Allen Date: Sun, 14 Mar 2021 15:42:27 -0400 Subject: [PATCH 07/41] Fix BEQZ tests --- wally-pipelined/src/ifu/icache.sv | 10 +++++----- wally-pipelined/src/ifu/ifu.sv | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/wally-pipelined/src/ifu/icache.sv b/wally-pipelined/src/ifu/icache.sv index 67a52800a..c5afe7847 100644 --- a/wally-pipelined/src/ifu/icache.sv +++ b/wally-pipelined/src/ifu/icache.sv @@ -68,9 +68,9 @@ module icache( // and then the upper word, in that order. generate if (`XLEN == 32) begin - assign InstrPAdrF = PCPF[1] ? (DelaySideF ? {PCPF[31:2]+1, 2'b00} : {PCPF[31:2], 2'b00}) : PCPF; + assign InstrPAdrF = PCPF[1] ? ((DelaySideF & ~CompressedF) ? {PCPF[31:2]+1, 2'b00} : {PCPF[31:2], 2'b00}) : PCPF; end else begin - assign InstrPAdrF = PCPF[2] ? (PCPF[1] ? (DelaySideF ? {PCPF[63:3]+1, 3'b000} : {PCPF[63:3], 3'b000}) : {PCPF[63:3], 3'b000}) : {PCPF[63:3], 3'b000}; + 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 // For now, we always read since the cache doesn't actually cache @@ -108,10 +108,10 @@ module icache( // 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 (DelayD & (MisalignedHalfInstrD[1:0] != 2'b11)) begin - assign InstrDMuxChoice = 2'b11; - end else if (FlushDLastCycle) begin + always_comb if (FlushDLastCycle) 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, DelaySideF}; end diff --git a/wally-pipelined/src/ifu/ifu.sv b/wally-pipelined/src/ifu/ifu.sv index 2fe212dde..e82767ed4 100644 --- a/wally-pipelined/src/ifu/ifu.sv +++ b/wally-pipelined/src/ifu/ifu.sv @@ -91,7 +91,7 @@ module ifu ( //assign InstrReadF = ~StallD; // *** & ICacheMissF; add later // assign InstrReadF = 1; // *** & ICacheMissF; add later - // jarred 2021-03-04 Add instrution cache block to remove rd2 + // jarred 2021-03-14 Add instrution cache block to remove rd2 assign PCPF = PCF; // Temporary workaround until iTLB is live icache ic(clk, reset, StallF, StallD, FlushD, PCPF, InstrInF, ICacheInstrPAdrF, InstrReadF, CompressedF, ICacheStallF, InstrRawD); // Prioritize the iTLB for reads if it wants one From 3fc36b978df1b539fa0e3e65a9186fc8e96535f6 Mon Sep 17 00:00:00 2001 From: Jarred Allen Date: Tue, 16 Mar 2021 16:57:51 -0400 Subject: [PATCH 08/41] Fix icache for jumping into misaligned instructions --- wally-pipelined/src/ifu/icache.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wally-pipelined/src/ifu/icache.sv b/wally-pipelined/src/ifu/icache.sv index c5afe7847..bef900088 100644 --- a/wally-pipelined/src/ifu/icache.sv +++ b/wally-pipelined/src/ifu/icache.sv @@ -51,7 +51,7 @@ module icache( flopr #(1) flushDLastCycleFlop(clk, reset, FlushD | (FlushDLastCycle & StallF), FlushDLastCycle); flopenr #(1) delayDFlop(clk, reset, ~StallF, DelayF, DelayD); flopenr #(1) delaySideDFlop(clk, reset, ~StallF, DelaySideF, DelaySideD); - flopenr #(1) delayStateFlop(clk, reset, ~StallF, DelayF & ~DelaySideF, DelaySideF); + flopenrc#(1) delayStateFlop(clk, reset, FlushD, ~StallF, DelayF & ~DelaySideF, DelaySideF); 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 From 11ba96f2e3b63d480b6cf7679a77274d654b5143 Mon Sep 17 00:00:00 2001 From: bbracker Date: Thu, 18 Mar 2021 17:47:00 -0400 Subject: [PATCH 09/41] maybe AHB works now --- wally-pipelined/regression/sim-wally-rv32ic | 2 +- wally-pipelined/regression/wally-pipelined.do | 57 +-------------- .../regression/wave-dos/ahb-waves.do | 73 +++++++++++++++++++ .../regression/wave-dos/default-waves.do | 56 ++++++++++++++ wally-pipelined/src/ebu/ahblite.sv | 61 ++++++++-------- wally-pipelined/src/uncore/dtim.sv | 35 +++++---- 6 files changed, 183 insertions(+), 101 deletions(-) create mode 100644 wally-pipelined/regression/wave-dos/ahb-waves.do create mode 100644 wally-pipelined/regression/wave-dos/default-waves.do diff --git a/wally-pipelined/regression/sim-wally-rv32ic b/wally-pipelined/regression/sim-wally-rv32ic index a254c8246..b69fb3172 100755 --- a/wally-pipelined/regression/sim-wally-rv32ic +++ b/wally-pipelined/regression/sim-wally-rv32ic @@ -1,3 +1,3 @@ vsim -c < Date: Thu, 18 Mar 2021 18:52:03 -0400 Subject: [PATCH 10/41] Add icache's read request to ahb wavs --- wally-pipelined/regression/wave-dos/ahb-waves.do | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/wally-pipelined/regression/wave-dos/ahb-waves.do b/wally-pipelined/regression/wave-dos/ahb-waves.do index ea0685816..3fe129939 100644 --- a/wally-pipelined/regression/wave-dos/ahb-waves.do +++ b/wally-pipelined/regression/wave-dos/ahb-waves.do @@ -22,6 +22,8 @@ add wave -hex /testbench/dut/hart/ifu/InstrD 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 @@ -70,4 +72,4 @@ add wave -hex /testbench/dut/hart/ieu/dp/ResultW add wave -hex /testbench/dut/hart/ieu/dp/RdW add wave -divider -add wave -hex -r /testbench/* \ No newline at end of file +add wave -hex -r /testbench/* From f069b759bec762da49241f96197d431c34e2ab57 Mon Sep 17 00:00:00 2001 From: Jarred Allen Date: Sat, 20 Mar 2021 17:04:13 -0400 Subject: [PATCH 11/41] Change flop to listen to StallF --- wally-pipelined/src/ifu/icache.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wally-pipelined/src/ifu/icache.sv b/wally-pipelined/src/ifu/icache.sv index bef900088..5b1f847e0 100644 --- a/wally-pipelined/src/ifu/icache.sv +++ b/wally-pipelined/src/ifu/icache.sv @@ -48,7 +48,7 @@ module icache( logic LastReadDataValidF; logic [`XLEN-1:0] LastReadDataF, LastReadAdrF, InDataF; - flopr #(1) flushDLastCycleFlop(clk, reset, FlushD | (FlushDLastCycle & StallF), FlushDLastCycle); + flopenr #(1) flushDLastCycleFlop(clk, reset, ~StallF, FlushD, FlushDLastCycle); flopenr #(1) delayDFlop(clk, reset, ~StallF, DelayF, DelayD); flopenr #(1) delaySideDFlop(clk, reset, ~StallF, DelaySideF, DelaySideD); flopenrc#(1) delayStateFlop(clk, reset, FlushD, ~StallF, DelayF & ~DelaySideF, DelaySideF); From 639a718312e13ca75264b3299fe434dfe4d2e9c7 Mon Sep 17 00:00:00 2001 From: Jarred Allen Date: Sat, 20 Mar 2021 17:16:50 -0400 Subject: [PATCH 12/41] Fix conflicts in ahb-waves that snuck through manual merging --- wally-pipelined/regression/wave-dos/ahb-waves.do | 7 ------- 1 file changed, 7 deletions(-) diff --git a/wally-pipelined/regression/wave-dos/ahb-waves.do b/wally-pipelined/regression/wave-dos/ahb-waves.do index 5a6e670fb..70609fa2a 100644 --- a/wally-pipelined/regression/wave-dos/ahb-waves.do +++ b/wally-pipelined/regression/wave-dos/ahb-waves.do @@ -63,12 +63,9 @@ add wave -hex /testbench/dut/hart/ebu/CaptureDataM add wave -hex /testbench/dut/hart/ebu/InstrStall add wave -divider -<<<<<<< HEAD add wave -hex /testbench/dut/uncore/dtim/* add wave -divider -======= ->>>>>>> origin/main add wave -hex /testbench/dut/hart/ifu/PCW add wave -hex /testbench/dut/hart/ifu/InstrW add wave /testbench/InstrWName @@ -78,11 +75,7 @@ add wave -hex /testbench/dut/hart/ieu/dp/ResultW add wave -hex /testbench/dut/hart/ieu/dp/RdW add wave -divider -<<<<<<< HEAD -add wave -hex -r /testbench/* -======= add wave -hex /testbench/dut/uncore/dtim/* add wave -divider add wave -hex -r /testbench/* ->>>>>>> origin/main From 43a8cb03542a864d290aeb3a2be098c2faab6112 Mon Sep 17 00:00:00 2001 From: Jarred Allen Date: Sat, 20 Mar 2021 17:34:19 -0400 Subject: [PATCH 13/41] Revert "Change flop to listen to StallF" This reverts commit f069b759bec762da49241f96197d431c34e2ab57. --- wally-pipelined/src/ifu/icache.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wally-pipelined/src/ifu/icache.sv b/wally-pipelined/src/ifu/icache.sv index 5b1f847e0..bef900088 100644 --- a/wally-pipelined/src/ifu/icache.sv +++ b/wally-pipelined/src/ifu/icache.sv @@ -48,7 +48,7 @@ module icache( logic LastReadDataValidF; logic [`XLEN-1:0] LastReadDataF, LastReadAdrF, InDataF; - flopenr #(1) flushDLastCycleFlop(clk, reset, ~StallF, FlushD, FlushDLastCycle); + flopr #(1) flushDLastCycleFlop(clk, reset, FlushD | (FlushDLastCycle & StallF), FlushDLastCycle); flopenr #(1) delayDFlop(clk, reset, ~StallF, DelayF, DelayD); flopenr #(1) delaySideDFlop(clk, reset, ~StallF, DelaySideF, DelaySideD); flopenrc#(1) delayStateFlop(clk, reset, FlushD, ~StallF, DelayF & ~DelaySideF, DelaySideF); From 665c244ba1767834f98adea6839d97ae59ca94f9 Mon Sep 17 00:00:00 2001 From: Jarred Allen Date: Sat, 20 Mar 2021 17:54:40 -0400 Subject: [PATCH 14/41] Fix another bug in the icache (why so many of them?) --- wally-pipelined/src/ifu/icache.sv | 12 ++++++++---- wally-pipelined/testbench/testbench-imperas.sv | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/wally-pipelined/src/ifu/icache.sv b/wally-pipelined/src/ifu/icache.sv index bef900088..29fef63d4 100644 --- a/wally-pipelined/src/ifu/icache.sv +++ b/wally-pipelined/src/ifu/icache.sv @@ -48,10 +48,14 @@ module icache( logic LastReadDataValidF; logic [`XLEN-1:0] LastReadDataF, LastReadAdrF, InDataF; + // 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 | (FlushDLastCycle & StallF), FlushDLastCycle); - flopenr #(1) delayDFlop(clk, reset, ~StallF, DelayF, DelayD); + + flopenr #(1) delayDFlop(clk, reset, ~StallF, DelayF & ~CompressedF, DelayD); flopenr #(1) delaySideDFlop(clk, reset, ~StallF, DelaySideF, DelaySideD); 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 @@ -68,7 +72,7 @@ module icache( // and then the upper word, in that order. generate if (`XLEN == 32) begin - assign InstrPAdrF = PCPF[1] ? ((DelaySideF & ~CompressedF) ? {PCPF[31:2]+1, 2'b00} : {PCPF[31:2], 2'b00}) : PCPF; + 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 @@ -101,7 +105,7 @@ module icache( assign ICacheStallF = 0; //DelayF & ~DelaySideF; // Detect if the instruction is compressed - assign CompressedF = (DelaySideF & DelayF) ? (MisalignedHalfInstrD[1:0] != 2'b11) : (InstrF[1:0] != 2'b11); + assign CompressedF = (DelayD) ? (MisalignedHalfInstrD[1:0] != 2'b11) : (InstrF[1:0] != 2'b11); // Pick the correct output, depending on whether we have to assemble this // instruction from two reads or not. @@ -113,7 +117,7 @@ module icache( end else if (DelayD & (MisalignedHalfInstrD[1:0] != 2'b11)) begin assign InstrDMuxChoice = 2'b11; end else begin - assign InstrDMuxChoice = {1'b0, DelaySideF}; + assign InstrDMuxChoice = {1'b0, DelayD}; end mux4 #(32) instrDMux (AlignedInstrD, {InstrInF[15:0], MisalignedHalfInstrD}, nop, {16'b0, MisalignedHalfInstrD}, InstrDMuxChoice, InstrRawD); endmodule diff --git a/wally-pipelined/testbench/testbench-imperas.sv b/wally-pipelined/testbench/testbench-imperas.sv index 8b128b17a..1060d8cbc 100644 --- a/wally-pipelined/testbench/testbench-imperas.sv +++ b/wally-pipelined/testbench/testbench-imperas.sv @@ -349,7 +349,7 @@ string tests32i[] = { end else begin // RV32 // *** add the 32 bit bp tests tests = {tests32i}; - if (`C_SUPPORTED % 2 == 1) tests = {tests, tests32ic}; + if (`C_SUPPORTED % 2 == 1) tests = {tests32ic, tests}; else tests = {tests, tests32iNOc}; if (`M_SUPPORTED % 2 == 1) tests = {tests, tests32m}; if (`A_SUPPORTED) tests = {tests, tests32a}; From 066dc2caacceca4e597fecc3619a0674687b0eb3 Mon Sep 17 00:00:00 2001 From: Jarred Allen Date: Sat, 20 Mar 2021 18:06:03 -0400 Subject: [PATCH 15/41] Fix bug with PC incrementing --- wally-pipelined/src/ifu/icache.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wally-pipelined/src/ifu/icache.sv b/wally-pipelined/src/ifu/icache.sv index 29fef63d4..a108ebb0b 100644 --- a/wally-pipelined/src/ifu/icache.sv +++ b/wally-pipelined/src/ifu/icache.sv @@ -105,7 +105,7 @@ module icache( assign ICacheStallF = 0; //DelayF & ~DelaySideF; // Detect if the instruction is compressed - assign CompressedF = (DelayD) ? (MisalignedHalfInstrD[1:0] != 2'b11) : (InstrF[1:0] != 2'b11); + 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. From e32291bcc23bbc439edf4002b19f508b3ebd0de9 Mon Sep 17 00:00:00 2001 From: Jarred Allen Date: Sat, 20 Mar 2021 18:19:51 -0400 Subject: [PATCH 16/41] Put Imperas testbench back --- wally-pipelined/testbench/testbench-imperas.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wally-pipelined/testbench/testbench-imperas.sv b/wally-pipelined/testbench/testbench-imperas.sv index 1060d8cbc..d4682dd20 100644 --- a/wally-pipelined/testbench/testbench-imperas.sv +++ b/wally-pipelined/testbench/testbench-imperas.sv @@ -349,7 +349,7 @@ string tests32i[] = { end else begin // RV32 // *** add the 32 bit bp tests tests = {tests32i}; - if (`C_SUPPORTED % 2 == 1) tests = {tests32ic, tests}; + if (`C_SUPPORTED % 2 == 1) tests = {tests, tests32ic}; else tests = {tests, tests32iNOc}; if (`M_SUPPORTED % 2 == 1) tests = {tests, tests32m}; if (`A_SUPPORTED) tests = {tests, tests32a}; @@ -483,7 +483,7 @@ string tests32i[] = { // initialize the branch predictor initial begin - $readmemb(`TWO_BIT_PRELOAD, dut.hart.ifu.bpred.Predictor.DirPredictor.PHT.memory); + $readmemb(`TWO_BIT_PRELOAD, dut.hart.ifu.bpred.DirPredictor.memory.memory); $readmemb(`BTB_PRELOAD, dut.hart.ifu.bpred.TargetPredictor.memory.memory); end From bab0e3b90fb668cc0843254298d8faeb5a66aee2 Mon Sep 17 00:00:00 2001 From: Jarred Allen Date: Sat, 20 Mar 2021 18:20:27 -0400 Subject: [PATCH 17/41] Change busybear testbench to reflect new location of InstrF --- wally-pipelined/regression/wally-busybear.do | 2 +- .../testbench/testbench-busybear.sv | 34 +++++++++---------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/wally-pipelined/regression/wally-busybear.do b/wally-pipelined/regression/wally-busybear.do index e4b75a083..636b3dbec 100644 --- a/wally-pipelined/regression/wally-busybear.do +++ b/wally-pipelined/regression/wally-busybear.do @@ -46,7 +46,7 @@ add wave -divider add wave -hex /testbench_busybear/PCtext add wave -hex /testbench_busybear/pcExpected add wave -hex /testbench_busybear/dut/hart/ifu/PCF -add wave -hex /testbench_busybear/dut/hart/ifu/InstrF +add wave -hex /testbench_busybear/dut/hart/ifu/ic/InstrF 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/InstrRawD diff --git a/wally-pipelined/testbench/testbench-busybear.sv b/wally-pipelined/testbench/testbench-busybear.sv index dcd1a4c87..df1e6e49f 100644 --- a/wally-pipelined/testbench/testbench-busybear.sv +++ b/wally-pipelined/testbench/testbench-busybear.sv @@ -356,10 +356,10 @@ module testbench_busybear(); logic [31:0] InstrMask; logic forcedInstr; logic [63:0] lastPCF; - always @(dut.PCF or dut.hart.ifu.InstrF or reset) begin + always @(dut.PCF or dut.hart.ifu.ic.InstrF or reset) begin if(~HWRITE) begin #3; - if (~reset && dut.hart.ifu.InstrF[15:0] !== {16{1'bx}} && ~dut.hart.StallD) begin + if (~reset && dut.hart.ifu.ic.InstrF[15:0] !== {16{1'bx}} && ~dut.hart.StallD) begin if (dut.PCF !== lastPCF) begin lastCheckInstrF = CheckInstrF; lastPC <= dut.PCF; @@ -367,23 +367,23 @@ module testbench_busybear(); if (speculative && (lastPC != pcExpected)) begin speculative = ~equal(dut.PCF,pcExpected,3); if(dut.PCF===pcExpected) begin - if(dut.hart.ifu.InstrF[6:0] == 7'b1010011) begin // for now, NOP out any float instrs + if(dut.hart.ifu.ic.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; + force dut.hart.ifu.ic.InstrF = 32'b0010011; #7; - release dut.hart.ifu.InstrF; + release dut.hart.ifu.ic.InstrF; $display("warning: NOPing out %s at PC=%0x, instr %0d, time %0t", PCtext, dut.PCF, instrs, $time); warningCount += 1; forcedInstr = 1; end else begin - if(dut.hart.ifu.InstrF[28:27] != 2'b11 && dut.hart.ifu.InstrF[6:0] == 7'b0101111) begin //for now, replace non-SC A instrs with LD + if(dut.hart.ifu.ic.InstrF[28:27] != 2'b11 && dut.hart.ifu.ic.InstrF[6:0] == 7'b0101111) begin //for now, replace non-SC A instrs with LD force CheckInstrF = {12'b0, CheckInstrF[19:7], 7'b0000011}; release CheckInstrF; - force dut.hart.ifu.InstrF = {12'b0, dut.hart.ifu.InstrF[19:7], 7'b0000011}; + force dut.hart.ifu.ic.InstrF = {12'b0, dut.hart.ifu.ic.InstrF[19:7], 7'b0000011}; #7; - release dut.hart.ifu.InstrF; + release dut.hart.ifu.ic.InstrF; $display("warning: replacing AMO instr %s at PC=%0x with ld", PCtext, dut.PCF); warningCount += 1; forcedInstr = 1; @@ -406,23 +406,23 @@ module testbench_busybear(); 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 + if(dut.hart.ifu.ic.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; + force dut.hart.ifu.ic.InstrF = 32'b0010011; #7; - release dut.hart.ifu.InstrF; + release dut.hart.ifu.ic.InstrF; $display("warning: NOPing out %s at PC=%0x, instr %0d, time %0t", PCtext, dut.PCF, instrs, $time); warningCount += 1; forcedInstr = 1; end else begin - if(dut.hart.ifu.InstrF[28:27] != 2'b11 && dut.hart.ifu.InstrF[6:0] == 7'b0101111) begin //for now, replace non-SC A instrs with LD + if(dut.hart.ifu.ic.InstrF[28:27] != 2'b11 && dut.hart.ifu.ic.InstrF[6:0] == 7'b0101111) begin //for now, replace non-SC A instrs with LD force CheckInstrF = {12'b0, CheckInstrF[19:7], 7'b0000011}; release CheckInstrF; - force dut.hart.ifu.InstrF = {12'b0, dut.hart.ifu.InstrF[19:7], 7'b0000011}; + force dut.hart.ifu.ic.InstrF = {12'b0, dut.hart.ifu.ic.InstrF[19:7], 7'b0000011}; #7; - release dut.hart.ifu.InstrF; + release dut.hart.ifu.ic.InstrF; $display("warning: replacing AMO instr %s at PC=%0x with ld", PCtext, dut.PCF); warningCount += 1; forcedInstr = 1; @@ -467,8 +467,8 @@ module testbench_busybear(); `ERROR end InstrMask = CheckInstrF[1:0] == 2'b11 ? 32'hFFFFFFFF : 32'h0000FFFF; - if ((~forcedInstr) && (~speculative) && ((InstrMask & dut.hart.ifu.InstrF) !== (InstrMask & CheckInstrF))) begin - $display("%0t ps, instr %0d: InstrF does not equal CheckInstrF: %x, %x, PC: %x", $time, instrs, dut.hart.ifu.InstrF, CheckInstrF, dut.PCF); + if ((~forcedInstr) && (~speculative) && ((InstrMask & dut.hart.ifu.ic.InstrF) !== (InstrMask & CheckInstrF))) begin + $display("%0t ps, instr %0d: InstrF does not equal CheckInstrF: %x, %x, PC: %x", $time, instrs, dut.hart.ifu.ic.InstrF, CheckInstrF, dut.PCF); `ERROR end end @@ -481,7 +481,7 @@ module testbench_busybear(); // Track names of instructions string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName; logic [31:0] 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, dut.hart.ifu.InstrD, dut.hart.ifu.InstrE, dut.hart.ifu.InstrM, InstrW, From 99fa8beef3df485b4dda81bd528a925fb37d9c29 Mon Sep 17 00:00:00 2001 From: Jarred Allen Date: Mon, 22 Mar 2021 15:04:46 -0400 Subject: [PATCH 18/41] Update icache interface --- wally-pipelined/src/ifu/icache.sv | 25 +++++++++++-------- wally-pipelined/src/ifu/ifu.sv | 7 +++++- .../testbench/testbench-imperas.sv | 2 +- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/wally-pipelined/src/ifu/icache.sv b/wally-pipelined/src/ifu/icache.sv index a108ebb0b..6ed1727d8 100644 --- a/wally-pipelined/src/ifu/icache.sv +++ b/wally-pipelined/src/ifu/icache.sv @@ -26,18 +26,19 @@ `include "wally-config.vh" module icache( - input logic clk, reset, - input logic StallF, StallD, - input logic FlushD, + input logic clk, reset, + input logic StallF, StallD, + input logic FlushD, // Fetch - input logic [`XLEN-1:0] PCPF, - input logic [`XLEN-1:0] InstrInF, - output logic [`XLEN-1:0] InstrPAdrF, - output logic InstrReadF, - output logic CompressedF, - output logic ICacheStallF, + input logic [`XLEN-1:12] UpperPCPF, + input logic [11:0] LowerPCF, + input logic [`XLEN-1:0] InstrInF, + output logic [`XLEN-1:0] InstrPAdrF, + output logic InstrReadF, + output logic CompressedF, + output logic ICacheStallF, // Decode - output logic [31:0] InstrRawD + output logic [31:0] InstrRawD ); logic DelayF, DelaySideF, FlushDLastCycle, DelayD, DelaySideD; @@ -48,6 +49,10 @@ module icache( logic LastReadDataValidF; logic [`XLEN-1:0] LastReadDataF, LastReadAdrF, InDataF; + // 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 | (FlushDLastCycle & StallF), FlushDLastCycle); diff --git a/wally-pipelined/src/ifu/ifu.sv b/wally-pipelined/src/ifu/ifu.sv index 99bf380fc..c92ff403a 100644 --- a/wally-pipelined/src/ifu/ifu.sv +++ b/wally-pipelined/src/ifu/ifu.sv @@ -93,7 +93,12 @@ module ifu ( // jarred 2021-03-14 Add instrution cache block to remove rd2 assign PCPF = PCF; // Temporary workaround until iTLB is live - icache ic(clk, reset, StallF, StallD, FlushD, PCPF, InstrInF, ICacheInstrPAdrF, InstrReadF, CompressedF, ICacheStallF, InstrRawD); + 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); diff --git a/wally-pipelined/testbench/testbench-imperas.sv b/wally-pipelined/testbench/testbench-imperas.sv index d4682dd20..8b128b17a 100644 --- a/wally-pipelined/testbench/testbench-imperas.sv +++ b/wally-pipelined/testbench/testbench-imperas.sv @@ -483,7 +483,7 @@ string tests32i[] = { // initialize the branch predictor initial begin - $readmemb(`TWO_BIT_PRELOAD, dut.hart.ifu.bpred.DirPredictor.memory.memory); + $readmemb(`TWO_BIT_PRELOAD, dut.hart.ifu.bpred.Predictor.DirPredictor.PHT.memory); $readmemb(`BTB_PRELOAD, dut.hart.ifu.bpred.TargetPredictor.memory.memory); end From 307e33bc7e6e7f0951ddd69d59752d1d7f1f5749 Mon Sep 17 00:00:00 2001 From: Jarred Allen Date: Mon, 22 Mar 2021 15:13:23 -0400 Subject: [PATCH 19/41] Remove DelaySideD since it isn't needed --- wally-pipelined/src/ifu/icache.sv | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/wally-pipelined/src/ifu/icache.sv b/wally-pipelined/src/ifu/icache.sv index 6ed1727d8..d7932eec2 100644 --- a/wally-pipelined/src/ifu/icache.sv +++ b/wally-pipelined/src/ifu/icache.sv @@ -41,7 +41,7 @@ module icache( output logic [31:0] InstrRawD ); - logic DelayF, DelaySideF, FlushDLastCycle, DelayD, DelaySideD; + logic DelayF, DelaySideF, FlushDLastCycle, DelayD; logic [1:0] InstrDMuxChoice; logic [15:0] MisalignedHalfInstrF, MisalignedHalfInstrD; logic [31:0] InstrF, AlignedInstrD; @@ -58,7 +58,6 @@ module icache( flopr #(1) flushDLastCycleFlop(clk, reset, FlushD | (FlushDLastCycle & StallF), FlushDLastCycle); flopenr #(1) delayDFlop(clk, reset, ~StallF, DelayF & ~CompressedF, DelayD); - flopenr #(1) delaySideDFlop(clk, reset, ~StallF, DelaySideF, DelaySideD); 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); @@ -82,8 +81,8 @@ module icache( 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 - // For now, we always read since the cache doesn't actually cache + // 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 @@ -107,7 +106,8 @@ module icache( assign MisalignedHalfInstrF = InDataF[63:48]; end endgenerate - assign ICacheStallF = 0; //DelayF & ~DelaySideF; + // 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; From 3c131bb2bdd1b15f28cee87201c6e4484f101795 Mon Sep 17 00:00:00 2001 From: Noah Boorstin Date: Mon, 22 Mar 2021 23:45:02 -0400 Subject: [PATCH 20/41] start migrating busybear over to InstrRawD/PCD this breaks busybear for now --- wally-pipelined/regression/wally-busybear.do | 8 +- .../testbench/testbench-busybear.sv | 86 +++++++++---------- 2 files changed, 47 insertions(+), 47 deletions(-) diff --git a/wally-pipelined/regression/wally-busybear.do b/wally-pipelined/regression/wally-busybear.do index 636b3dbec..b7e92ae3f 100644 --- a/wally-pipelined/regression/wally-busybear.do +++ b/wally-pipelined/regression/wally-busybear.do @@ -45,13 +45,13 @@ add wave /testbench_busybear/reset add wave -divider add wave -hex /testbench_busybear/PCtext add wave -hex /testbench_busybear/pcExpected -add wave -hex /testbench_busybear/dut/hart/ifu/PCF -add wave -hex /testbench_busybear/dut/hart/ifu/ic/InstrF +add wave -hex /testbench_busybear/dut/hart/ifu/PCD +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/FlushD add wave -hex /testbench_busybear/dut/hart/ifu/InstrRawD -add wave /testbench_busybear/CheckInstrF -add wave /testbench_busybear/lastCheckInstrF +add wave /testbench_busybear/CheckInstrD +add wave /testbench_busybear/lastCheckInstrD add wave /testbench_busybear/speculative add wave /testbench_busybear/lastPC2 add wave -divider diff --git a/wally-pipelined/testbench/testbench-busybear.sv b/wally-pipelined/testbench/testbench-busybear.sv index d4c5ed9d2..596241060 100644 --- a/wally-pipelined/testbench/testbench-busybear.sv +++ b/wally-pipelined/testbench/testbench-busybear.sv @@ -7,7 +7,7 @@ module testbench_busybear(); logic [31:0] GPIOPinsOut, GPIOPinsEn; // instantiate device to be tested - logic [31:0] CheckInstrF; + logic [31:0] CheckInstrD; logic [`AHBW-1:0] HRDATA; logic [31:0] HADDR; @@ -344,7 +344,7 @@ module testbench_busybear(); initial begin speculative = 0; end - logic [63:0] lastCheckInstrF, lastPC, lastPC2; + logic [63:0] lastCheckInstrD, lastPC, lastPC2; string PCtextW, PCtext2W; logic [31:0] InstrWExpected; @@ -379,36 +379,36 @@ module testbench_busybear(); end logic [31:0] InstrMask; logic forcedInstr; - logic [63:0] lastPCF; - always @(dut.PCF or dut.hart.ifu.ic.InstrF or reset) begin + logic [63:0] lastPCD; + always @(dut.hart.ifu.PCD or dut.hart.ifu.InstrRawD or reset) begin if(~HWRITE) begin #3; - if (~reset && dut.hart.ifu.ic.InstrF[15:0] !== {16{1'bx}} && ~dut.hart.StallD) begin - if (dut.PCF !== lastPCF) begin - lastCheckInstrF = CheckInstrF; - lastPC <= dut.PCF; + if (~reset && dut.hart.ifu.InstrRawD[15:0] !== {16{1'bx}} && ~dut.hart.StallD) begin + if (dut.hart.ifu.PCD !== lastPCD) begin + lastCheckInstrD = CheckInstrD; + lastPC <= dut.hart.ifu.PCD; lastPC2 <= lastPC; if (speculative && (lastPC != pcExpected)) begin - speculative = ~equal(dut.PCF,pcExpected,3); - if(dut.PCF===pcExpected) begin - if(dut.hart.ifu.ic.InstrF[6:0] == 7'b1010011) begin // for now, NOP out any float instrs - force CheckInstrF = 32'b0010011; - release CheckInstrF; - force dut.hart.ifu.ic.InstrF = 32'b0010011; + speculative = ~equal(dut.hart.ifu.PCD,pcExpected,3); + if(dut.hart.ifu.PCD===pcExpected) begin + if(dut.hart.ifu.InstrRawD[6:0] == 7'b1010011) begin // for now, NOP out any float instrs + force CheckInstrD = 32'b0010011; + release CheckInstrD; + force dut.hart.ifu.InstrRawD = 32'b0010011; #7; - release dut.hart.ifu.ic.InstrF; - $display("warning: NOPing out %s at PC=%0x, instr %0d, time %0t", PCtext, dut.PCF, instrs, $time); + release dut.hart.ifu.InstrRawD; + $display("warning: NOPing out %s at PC=%0x, instr %0d, time %0t", PCtext, dut.hart.ifu.PCD, instrs, $time); warningCount += 1; forcedInstr = 1; end else begin - if(dut.hart.ifu.ic.InstrF[28:27] != 2'b11 && dut.hart.ifu.ic.InstrF[6:0] == 7'b0101111) begin //for now, replace non-SC A instrs with LD - force CheckInstrF = {12'b0, CheckInstrF[19:7], 7'b0000011}; - release CheckInstrF; - force dut.hart.ifu.ic.InstrF = {12'b0, dut.hart.ifu.ic.InstrF[19:7], 7'b0000011}; + if(dut.hart.ifu.InstrRawD[28:27] != 2'b11 && dut.hart.ifu.InstrRawD[6:0] == 7'b0101111) begin //for now, replace non-SC A instrs with LD + force CheckInstrD = {12'b0, CheckInstrD[19:7], 7'b0000011}; + release CheckInstrD; + force dut.hart.ifu.InstrRawD = {12'b0, dut.hart.ifu.InstrRawD[19:7], 7'b0000011}; #7; - release dut.hart.ifu.ic.InstrF; - $display("warning: replacing AMO instr %s at PC=%0x with ld", PCtext, dut.PCF); + release dut.hart.ifu.InstrRawD; + $display("warning: replacing AMO instr %s at PC=%0x with ld", PCtext, dut.hart.ifu.PCD); warningCount += 1; forcedInstr = 1; end @@ -428,26 +428,26 @@ module testbench_busybear(); 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.ic.InstrF[6:0] == 7'b1010011) begin // for now, NOP out any float instrs - force CheckInstrF = 32'b0010011; - release CheckInstrF; - force dut.hart.ifu.ic.InstrF = 32'b0010011; + scan_file_PC = $fscanf(data_file_PC, "%x\n", CheckInstrD); + if(dut.hart.ifu.PCD === pcExpected) begin + if(dut.hart.ifu.InstrRawD[6:0] == 7'b1010011) begin // for now, NOP out any float instrs + force CheckInstrD = 32'b0010011; + release CheckInstrD; + force dut.hart.ifu.InstrRawD = 32'b0010011; #7; - release dut.hart.ifu.ic.InstrF; - $display("warning: NOPing out %s at PC=%0x, instr %0d, time %0t", PCtext, dut.PCF, instrs, $time); + release dut.hart.ifu.InstrRawD; + $display("warning: NOPing out %s at PC=%0x, instr %0d, time %0t", PCtext, dut.hart.ifu.PCD, instrs, $time); warningCount += 1; forcedInstr = 1; end else begin - if(dut.hart.ifu.ic.InstrF[28:27] != 2'b11 && dut.hart.ifu.ic.InstrF[6:0] == 7'b0101111) begin //for now, replace non-SC A instrs with LD - force CheckInstrF = {12'b0, CheckInstrF[19:7], 7'b0000011}; - release CheckInstrF; - force dut.hart.ifu.ic.InstrF = {12'b0, dut.hart.ifu.ic.InstrF[19:7], 7'b0000011}; + if(dut.hart.ifu.InstrRawD[28:27] != 2'b11 && dut.hart.ifu.InstrRawD[6:0] == 7'b0101111) begin //for now, replace non-SC A instrs with LD + force CheckInstrD = {12'b0, CheckInstrD[19:7], 7'b0000011}; + release CheckInstrD; + force dut.hart.ifu.InstrRawD = {12'b0, dut.hart.ifu.InstrRawD[19:7], 7'b0000011}; #7; - release dut.hart.ifu.ic.InstrF; - $display("warning: replacing AMO instr %s at PC=%0x with ld", PCtext, dut.PCF); + release dut.hart.ifu.InstrRawD; + $display("warning: replacing AMO instr %s at PC=%0x with ld", PCtext, dut.hart.ifu.PCD); warningCount += 1; forcedInstr = 1; end @@ -465,7 +465,7 @@ module testbench_busybear(); end instrs += 1; // are we at a branch/jump? - casex (lastCheckInstrF[31:0]) + casex (lastCheckInstrD[31:0]) 32'b00000000001000000000000001110011, // URET 32'b00010000001000000000000001110011, // SRET 32'b00110000001000000000000001110011, // MRET @@ -486,18 +486,18 @@ module testbench_busybear(); endcase //check things! - if ((~speculative) && (~equal(dut.PCF,pcExpected,3))) begin - $display("%0t ps, instr %0d: PC does not equal PC expected: %x, %x", $time, instrs, dut.PCF, pcExpected); + 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.hart.ifu.PCD, pcExpected); `ERROR end - InstrMask = CheckInstrF[1:0] == 2'b11 ? 32'hFFFFFFFF : 32'h0000FFFF; - if ((~forcedInstr) && (~speculative) && ((InstrMask & dut.hart.ifu.ic.InstrF) !== (InstrMask & CheckInstrF))) begin - $display("%0t ps, instr %0d: InstrF does not equal CheckInstrF: %x, %x, PC: %x", $time, instrs, dut.hart.ifu.ic.InstrF, CheckInstrF, dut.PCF); + InstrMask = CheckInstrD[1:0] == 2'b11 ? 32'hFFFFFFFF : 32'h0000FFFF; + if ((~forcedInstr) && (~speculative) && ((InstrMask & dut.hart.ifu.InstrRawD) !== (InstrMask & CheckInstrD))) begin + $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 end end end - lastPCF = dut.PCF; + lastPCD = dut.hart.ifu.PCD; end end end From c47a80213e198a0e6b0039c70bab95416db300fa Mon Sep 17 00:00:00 2001 From: Jarred Allen Date: Mon, 22 Mar 2021 23:57:01 -0400 Subject: [PATCH 21/41] Small commit to see if new hook tests non-main branch --- wally-pipelined/src/ifu/icache.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wally-pipelined/src/ifu/icache.sv b/wally-pipelined/src/ifu/icache.sv index d7932eec2..ceb06ddce 100644 --- a/wally-pipelined/src/ifu/icache.sv +++ b/wally-pipelined/src/ifu/icache.sv @@ -4,7 +4,7 @@ // Written: jaallen@g.hmc.edu 2021-03-02 // Modified: // -// Purpose: Cache instructions for the ifu so it can access memory less often +// Purpose: Cache instructions for the ifu so it can access memory less often, saving cycles // // A component of the Wally configurable RISC-V project. // From e4ebb4e31e5581528da670a23602adc062141cab Mon Sep 17 00:00:00 2001 From: Jarred Allen Date: Tue, 23 Mar 2021 00:07:39 -0400 Subject: [PATCH 22/41] Add comments explaining icache inputs --- wally-pipelined/src/ifu/icache.sv | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/wally-pipelined/src/ifu/icache.sv b/wally-pipelined/src/ifu/icache.sv index ceb06ddce..98a58f7d7 100644 --- a/wally-pipelined/src/ifu/icache.sv +++ b/wally-pipelined/src/ifu/icache.sv @@ -26,18 +26,25 @@ `include "wally-config.vh" module icache( + // Basic pipeline stuff input logic clk, reset, input logic StallF, StallD, input logic FlushD, - // Fetch + // 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, - // Decode + // 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 ); From 34cc9b4aeb9b891115b9b41df8579863062e07dd Mon Sep 17 00:00:00 2001 From: Jarred Allen Date: Tue, 23 Mar 2021 00:10:35 -0400 Subject: [PATCH 23/41] Document some internal signals --- wally-pipelined/src/ifu/icache.sv | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/wally-pipelined/src/ifu/icache.sv b/wally-pipelined/src/ifu/icache.sv index 98a58f7d7..2eab6ed81 100644 --- a/wally-pipelined/src/ifu/icache.sv +++ b/wally-pipelined/src/ifu/icache.sv @@ -52,10 +52,13 @@ module icache( logic [1:0] InstrDMuxChoice; logic [15:0] MisalignedHalfInstrF, MisalignedHalfInstrD; logic [31:0] InstrF, AlignedInstrD; - logic [31:0] nop = 32'h00000013; // instruction for NOP + // 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}; From 7fb2ebec50ff3548f4eef945fee493470a51df9c Mon Sep 17 00:00:00 2001 From: Noah Boorstin Date: Tue, 23 Mar 2021 13:28:44 -0400 Subject: [PATCH 24/41] busybear: ignore illegal instruction when starting --- .../testbench/testbench-busybear.sv | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/wally-pipelined/testbench/testbench-busybear.sv b/wally-pipelined/testbench/testbench-busybear.sv index 596241060..65c6dc371 100644 --- a/wally-pipelined/testbench/testbench-busybear.sv +++ b/wally-pipelined/testbench/testbench-busybear.sv @@ -282,14 +282,16 @@ module testbench_busybear(); //CSR checking \ always @(``PATH``.``CSR``_REGW) begin \ if ($time > 1) begin \ - scan_file_csr = $fscanf(data_file_csr, "%s\n", CSR); \ - scan_file_csr = $fscanf(data_file_csr, "%x\n", expected``CSR``); \ - if(CSR.icompare(`"CSR`")) begin \ - $display("%0t ps, instr %0d: %s changed, expected %s", $time, instrs, `"CSR`", CSR); \ - end \ - if(``PATH``.``CSR``_REGW != ``expected``CSR) begin \ - $display("%0t ps, instr %0d: %s does not equal %s expected: %x, %x", $time, instrs, `"CSR`", CSR, ``PATH``.``CSR``_REGW, ``expected``CSR); \ - `ERROR \ + if (instrs != 0) begin \ + scan_file_csr = $fscanf(data_file_csr, "%s\n", CSR); \ + scan_file_csr = $fscanf(data_file_csr, "%x\n", expected``CSR``); \ + if(CSR.icompare(`"CSR`")) begin \ + $display("%0t ps, instr %0d: %s changed, expected %s", $time, instrs, `"CSR`", CSR); \ + end \ + if(``PATH``.``CSR``_REGW != ``expected``CSR) begin \ + $display("%0t ps, instr %0d: %s does not equal %s expected: %x, %x", $time, instrs, `"CSR`", CSR, ``PATH``.``CSR``_REGW, ``expected``CSR); \ + `ERROR \ + end \ end \ end else begin \ for(integer j=0; j Date: Tue, 23 Mar 2021 14:06:21 -0400 Subject: [PATCH 25/41] busybear: more progress moving from instrf to instrrawd --- .../testbench/testbench-busybear.sv | 190 +++++++++--------- 1 file changed, 95 insertions(+), 95 deletions(-) diff --git a/wally-pipelined/testbench/testbench-busybear.sv b/wally-pipelined/testbench/testbench-busybear.sv index 65c6dc371..385c45d5f 100644 --- a/wally-pipelined/testbench/testbench-busybear.sv +++ b/wally-pipelined/testbench/testbench-busybear.sv @@ -262,7 +262,7 @@ module testbench_busybear(); end 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("(as a reminder, MCAUSE and MEPC are set by this)"); $display("at %0t ps, instr %0d, HADDR %x", $time, instrs, HADDR); @@ -282,7 +282,7 @@ module testbench_busybear(); //CSR checking \ always @(``PATH``.``CSR``_REGW) begin \ if ($time > 1) begin \ - if (instrs != 0) begin \ + if (instrs > 1) begin \ scan_file_csr = $fscanf(data_file_csr, "%s\n", CSR); \ scan_file_csr = $fscanf(data_file_csr, "%x\n", expected``CSR``); \ if(CSR.icompare(`"CSR`")) begin \ @@ -384,123 +384,123 @@ module testbench_busybear(); logic [63:0] lastPCD; always @(dut.hart.ifu.PCD or dut.hart.ifu.InstrRawD or reset) begin if(~HWRITE) begin - #3; - if (~reset && dut.hart.ifu.InstrRawD[15:0] !== {16{1'bx}} && ~dut.hart.StallD) begin - if (dut.hart.ifu.PCD !== lastPCD) begin - lastCheckInstrD = CheckInstrD; - lastPC <= dut.hart.ifu.PCD; - lastPC2 <= lastPC; - if (speculative && (lastPC != pcExpected)) begin - speculative = ~equal(dut.hart.ifu.PCD,pcExpected,3); - if(dut.hart.ifu.PCD===pcExpected) begin - if(dut.hart.ifu.InstrRawD[6:0] == 7'b1010011) begin // for now, NOP out any float instrs - force CheckInstrD = 32'b0010011; - release CheckInstrD; - force dut.hart.ifu.InstrRawD = 32'b0010011; - #7; - release dut.hart.ifu.InstrRawD; - $display("warning: NOPing out %s at PC=%0x, instr %0d, time %0t", PCtext, dut.hart.ifu.PCD, instrs, $time); - warningCount += 1; - forcedInstr = 1; - end - else begin - if(dut.hart.ifu.InstrRawD[28:27] != 2'b11 && dut.hart.ifu.InstrRawD[6:0] == 7'b0101111) begin //for now, replace non-SC A instrs with LD - force CheckInstrD = {12'b0, CheckInstrD[19:7], 7'b0000011}; + #3; + if (~reset && dut.hart.ifu.InstrRawD[15:0] !== {16{1'bx}} && dut.hart.ifu.PCD !== 64'h0) begin + if (dut.hart.ifu.PCD !== lastPCD) begin + lastCheckInstrD = CheckInstrD; + lastPC <= dut.hart.ifu.PCD; + lastPC2 <= lastPC; + if (speculative && (lastPC != pcExpected)) begin + speculative = ~equal(dut.hart.ifu.PCD,pcExpected,3); + if(dut.hart.ifu.PCD===pcExpected) begin + if(dut.hart.ifu.InstrRawD[6:0] == 7'b1010011) begin // for now, NOP out any float instrs + force CheckInstrD = 32'b0010011; release CheckInstrD; - force dut.hart.ifu.InstrRawD = {12'b0, dut.hart.ifu.InstrRawD[19:7], 7'b0000011}; + force dut.hart.ifu.InstrRawD = 32'b0010011; #7; release dut.hart.ifu.InstrRawD; - $display("warning: replacing AMO instr %s at PC=%0x with ld", PCtext, dut.hart.ifu.PCD); + $display("warning: NOPing out %s at PC=%0x, instr %0d, time %0t", PCtext, dut.hart.ifu.PCD, instrs, $time); warningCount += 1; forcedInstr = 1; end else begin - forcedInstr = 0; + if(dut.hart.ifu.InstrRawD[28:27] != 2'b11 && dut.hart.ifu.InstrRawD[6:0] == 7'b0101111) begin //for now, replace non-SC A instrs with LD + force CheckInstrD = {12'b0, CheckInstrD[19:7], 7'b0000011}; + release CheckInstrD; + force dut.hart.ifu.InstrRawD = {12'b0, dut.hart.ifu.InstrRawD[19:7], 7'b0000011}; + #7; + release dut.hart.ifu.InstrRawD; + $display("warning: replacing AMO instr %s at PC=%0x with ld", PCtext, dut.hart.ifu.PCD); + warningCount += 1; + forcedInstr = 1; + end + else begin + forcedInstr = 0; + end end end end - end - else begin - if($feof(data_file_PC)) begin - $display("no more PC data to read"); - `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", CheckInstrD); - if(dut.hart.ifu.PCD === pcExpected) begin - if(dut.hart.ifu.InstrRawD[6:0] == 7'b1010011) begin // for now, NOP out any float instrs - force CheckInstrD = 32'b0010011; - release CheckInstrD; - force dut.hart.ifu.InstrRawD = 32'b0010011; - #7; - release dut.hart.ifu.InstrRawD; - $display("warning: NOPing out %s at PC=%0x, instr %0d, time %0t", PCtext, dut.hart.ifu.PCD, instrs, $time); - warningCount += 1; - forcedInstr = 1; + else begin + if($feof(data_file_PC)) begin + $display("no more PC data to read"); + `ERROR end - else begin - if(dut.hart.ifu.InstrRawD[28:27] != 2'b11 && dut.hart.ifu.InstrRawD[6:0] == 7'b0101111) begin //for now, replace non-SC A instrs with LD - force CheckInstrD = {12'b0, CheckInstrD[19:7], 7'b0000011}; + 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", CheckInstrD); + if(dut.hart.ifu.PCD === pcExpected) begin + if(dut.hart.ifu.InstrRawD[6:0] == 7'b1010011) begin // for now, NOP out any float instrs + force CheckInstrD = 32'b0010011; release CheckInstrD; - force dut.hart.ifu.InstrRawD = {12'b0, dut.hart.ifu.InstrRawD[19:7], 7'b0000011}; + force dut.hart.ifu.InstrRawD = 32'b0010011; #7; release dut.hart.ifu.InstrRawD; - $display("warning: replacing AMO instr %s at PC=%0x with ld", PCtext, dut.hart.ifu.PCD); + $display("warning: NOPing out %s at PC=%0x, instr %0d, time %0t", PCtext, dut.hart.ifu.PCD, instrs, $time); warningCount += 1; forcedInstr = 1; end else begin - forcedInstr = 0; + if(dut.hart.ifu.InstrRawD[28:27] != 2'b11 && dut.hart.ifu.InstrRawD[6:0] == 7'b0101111) begin //for now, replace non-SC A instrs with LD + force CheckInstrD = {12'b0, CheckInstrD[19:7], 7'b0000011}; + release CheckInstrD; + force dut.hart.ifu.InstrRawD = {12'b0, dut.hart.ifu.InstrRawD[19:7], 7'b0000011}; + #7; + release dut.hart.ifu.InstrRawD; + $display("warning: replacing AMO instr %s at PC=%0x with ld", PCtext, dut.hart.ifu.PCD); + warningCount += 1; + forcedInstr = 1; + end + else begin + forcedInstr = 0; + end end end - end - // then expected PC value - scan_file_PC = $fscanf(data_file_PC, "%x\n", pcExpected); - if (instrs <= 10 || (instrs <= 100 && instrs % 10 == 0) || - (instrs <= 1000 && instrs % 100 == 0) || (instrs <= 10000 && instrs % 1000 == 0) || - (instrs <= 100000 && instrs % 10000 == 0) || (instrs <= 1000000 && instrs % 100000 == 0)) begin - $display("loaded %0d instructions", instrs); - end - instrs += 1; - // are we at a branch/jump? - casex (lastCheckInstrD[31:0]) - 32'b00000000001000000000000001110011, // URET - 32'b00010000001000000000000001110011, // SRET - 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 + // then expected PC value + scan_file_PC = $fscanf(data_file_PC, "%x\n", pcExpected); + if (instrs <= 10 || (instrs <= 100 && instrs % 10 == 0) || + (instrs <= 1000 && instrs % 100 == 0) || (instrs <= 10000 && instrs % 1000 == 0) || + (instrs <= 100000 && instrs % 10000 == 0) || (instrs <= 1000000 && instrs % 100000 == 0)) begin + $display("loaded %0d instructions", instrs); + end + instrs += 1; + // are we at a branch/jump? + casex (lastCheckInstrD[31:0]) + 32'b00000000001000000000000001110011, // URET + 32'b00010000001000000000000001110011, // SRET + 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! - 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.hart.ifu.PCD, pcExpected); - `ERROR - end - InstrMask = CheckInstrD[1:0] == 2'b11 ? 32'hFFFFFFFF : 32'h0000FFFF; - if ((~forcedInstr) && (~speculative) && ((InstrMask & dut.hart.ifu.InstrRawD) !== (InstrMask & CheckInstrD))) begin - $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 + //check things! + 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.hart.ifu.PCD, pcExpected); + `ERROR + end + InstrMask = CheckInstrD[1:0] == 2'b11 ? 32'hFFFFFFFF : 32'h0000FFFF; + if ((~forcedInstr) && (~speculative) && ((InstrMask & dut.hart.ifu.InstrRawD) !== (InstrMask & CheckInstrD))) begin + $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 + end end end + lastPCD = dut.hart.ifu.PCD; end - lastPCD = dut.hart.ifu.PCD; - end end end From c16605a10585a7be1e93178ebbabe95d62262a5f Mon Sep 17 00:00:00 2001 From: Jarred Allen Date: Tue, 23 Mar 2021 14:17:01 -0400 Subject: [PATCH 26/41] Remove deleted signal from waves --- wally-pipelined/regression/wave-dos/ahb-waves.do | 1 - wally-pipelined/regression/wave-dos/default-waves.do | 1 - 2 files changed, 2 deletions(-) diff --git a/wally-pipelined/regression/wave-dos/ahb-waves.do b/wally-pipelined/regression/wave-dos/ahb-waves.do index 70609fa2a..f043d779e 100644 --- a/wally-pipelined/regression/wave-dos/ahb-waves.do +++ b/wally-pipelined/regression/wave-dos/ahb-waves.do @@ -28,7 +28,6 @@ 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 /testbench/dut/hart/ifu/ic/DelaySideD add wave -hex /testbench/dut/hart/ifu/ic/MisalignedHalfInstrD add wave -divider diff --git a/wally-pipelined/regression/wave-dos/default-waves.do b/wally-pipelined/regression/wave-dos/default-waves.do index aff5f3807..4b6456512 100644 --- a/wally-pipelined/regression/wave-dos/default-waves.do +++ b/wally-pipelined/regression/wave-dos/default-waves.do @@ -27,7 +27,6 @@ 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 /testbench/dut/hart/ifu/ic/DelaySideD add wave -hex /testbench/dut/hart/ifu/ic/MisalignedHalfInstrD add wave -divider add wave -hex /testbench/dut/hart/ifu/PCE From 355961f834dfdfc7b57ed5ea3dcff23399ae1a3c Mon Sep 17 00:00:00 2001 From: Noah Boorstin Date: Tue, 23 Mar 2021 14:49:26 -0400 Subject: [PATCH 27/41] busybear: more progress --- wally-pipelined/regression/wally-busybear.do | 2 ++ wally-pipelined/testbench/testbench-busybear.sv | 15 +++++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/wally-pipelined/regression/wally-busybear.do b/wally-pipelined/regression/wally-busybear.do index b7e92ae3f..71444cdbd 100644 --- a/wally-pipelined/regression/wally-busybear.do +++ b/wally-pipelined/regression/wally-busybear.do @@ -49,6 +49,8 @@ add wave -hex /testbench_busybear/dut/hart/ifu/PCD 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/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 /testbench_busybear/CheckInstrD add wave /testbench_busybear/lastCheckInstrD diff --git a/wally-pipelined/testbench/testbench-busybear.sv b/wally-pipelined/testbench/testbench-busybear.sv index 385c45d5f..254e672d8 100644 --- a/wally-pipelined/testbench/testbench-busybear.sv +++ b/wally-pipelined/testbench/testbench-busybear.sv @@ -192,7 +192,7 @@ module testbench_busybear(); always @(dut.HRDATA) begin #1; - if (dut.hart.MemRWM[1] && HADDR != dut.PCF && dut.HRDATA !== {64{1'bx}}) begin + if (dut.hart.MemRWM[1] && HADDR[31:3] != dut.PCF[31:3] && dut.HRDATA !== {64{1'bx}}) begin //$display("%0t", $time); if($feof(data_file_memR)) begin $display("no more memR data to read"); @@ -335,6 +335,13 @@ module testbench_busybear(); `CHECK_CSR2(STVAL, `CSRS) `CHECK_CSR(STVEC) + initial begin //this is just fun to make causes easier to understand + #38; + force dut.hart.priv.csr.genblk1.csrm.NextCauseM = 0; + #16; + release dut.hart.priv.csr.genblk1.csrm.NextCauseM; + end + initial begin //this is temporary until the bug can be fixed!!! #18909760; force dut.hart.ieu.dp.regf.rf[5] = 64'h0000000080000004; @@ -382,10 +389,10 @@ module testbench_busybear(); logic [31:0] InstrMask; logic forcedInstr; logic [63:0] lastPCD; - always @(dut.hart.ifu.PCD or dut.hart.ifu.InstrRawD 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 - #3; - if (~reset && dut.hart.ifu.InstrRawD[15:0] !== {16{1'bx}} && dut.hart.ifu.PCD !== 64'h0) begin + #2; + if (~reset && dut.hart.ifu.InstrRawD[15:0] !== {16{1'bx}} && dut.hart.ifu.PCD !== 64'h0 && ~dut.hart.ifu.StallE) begin if (dut.hart.ifu.PCD !== lastPCD) begin lastCheckInstrD = CheckInstrD; lastPC <= dut.hart.ifu.PCD; From ebd2c60b74c6cd665c0fd8698dc0cc1a9db6bd80 Mon Sep 17 00:00:00 2001 From: Jarred Allen Date: Tue, 23 Mar 2021 17:03:02 -0400 Subject: [PATCH 28/41] Begin work on direct-mapped cache --- wally-pipelined/src/cache/dmapped.sv | 91 ++++++++++++++++++++++++++++ wally-pipelined/src/cache/line.sv | 60 ++++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 wally-pipelined/src/cache/dmapped.sv create mode 100644 wally-pipelined/src/cache/line.sv diff --git a/wally-pipelined/src/cache/dmapped.sv b/wally-pipelined/src/cache/dmapped.sv new file mode 100644 index 000000000..b57f24017 --- /dev/null +++ b/wally-pipelined/src/cache/dmapped.sv @@ -0,0 +1,91 @@ +/////////////////////////////////////////// +// dmapped.sv +// +// Written: jaallen@g.hmc.edu 2021-03-23 +// Modified: +// +// Purpose: An implementation of a direct-mapped cache memory +// +// 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 rodirectmapped #(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] UpperPAdr, + input logic [11:0] LowerAdr, + // 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 +); + + integer TAGWIDTH = `XLEN-$clog2(NUMLINES)-$clog2(LINESIZE); + integer SETWIDTH = $clog2(NUMLINES); + integer OFFSETWIDTH = $clog2(LINESIZE/8); + + logic [NUMLINES-1:0][WORDSIZE-1:0] LineOutputs; + logic [NUMLINES-1:0] ValidOutputs; + logic [NUMLINES-1:0][TAGSIZE-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 = LowerAdr[OFFSETWIDTH-1:0]; + assign ReadPAdr = {UpperPAdr, LowerAdr}; + 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, TAGSIZE, WORDSIZE) lines[NUMLINES]( + .*, + .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 diff --git a/wally-pipelined/src/cache/line.sv b/wally-pipelined/src/cache/line.sv new file mode 100644 index 000000000..85d4073bd --- /dev/null +++ b/wally-pipelined/src/cache/line.sv @@ -0,0 +1,60 @@ +/////////////////////////////////////////// +// 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 +); + + logic [LINESIZE-1:0] DataLine; + logic [$clog2(LINESIZE/8)-1:0] AlignedWordSelect; + + flopenr #(1) ValidBitFlop(clk, reset, WriteEnable | flush, ~flush, DataValid); + flopenr #(TAGSIZE) TagFlop(clk, reset, WriteEnable, WriteTag, DataTag); + flopenr #(LINESIZE) LineFlop(clk, reset, WriteEnable, WriteData, DataLine); + + + always_comb begin + assign AlignedWordSelect = {WordSelect[$clog2(LINESIZE/8)-1:$clog2(WORDSIZE)], {$clog2(WORDSIZE){'b0}}}; + assign DataWord = DataLine[WORDSIZE+AlignedWordSelect-1:AlignedWordSelect]; + end + +endmodule From abf9f3b3cb961207e5b4ed27b8a719552b238ed4 Mon Sep 17 00:00:00 2001 From: Jarred Allen Date: Wed, 24 Mar 2021 00:58:56 -0400 Subject: [PATCH 29/41] Fix compile errors from const not actually being constant (why does Verilog do this) --- wally-pipelined/src/cache/dmapped.sv | 12 ++++++------ wally-pipelined/src/cache/line.sv | 18 +++++++++++++----- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/wally-pipelined/src/cache/dmapped.sv b/wally-pipelined/src/cache/dmapped.sv index b57f24017..52027b390 100644 --- a/wally-pipelined/src/cache/dmapped.sv +++ b/wally-pipelined/src/cache/dmapped.sv @@ -43,13 +43,13 @@ module rodirectmapped #(parameter LINESIZE = 256, parameter NUMLINES = 512, para output logic DataValid ); - integer TAGWIDTH = `XLEN-$clog2(NUMLINES)-$clog2(LINESIZE); - integer SETWIDTH = $clog2(NUMLINES); - integer OFFSETWIDTH = $clog2(LINESIZE/8); + 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][TAGSIZE-1:0] TagOutputs; + logic [NUMLINES-1:0][TAGWIDTH-1:0] TagOutputs; logic [OFFSETWIDTH-1:0] WordSelect; logic [`XLEN-1:0] ReadPAdr; logic [SETWIDTH-1:0] ReadSet, WriteSet; @@ -70,14 +70,14 @@ module rodirectmapped #(parameter LINESIZE = 256, parameter NUMLINES = 512, para genvar i; generate for (i=0; i < NUMLINES; i++) begin - rocacheline #(LINESIZE, TAGSIZE, WORDSIZE) lines[NUMLINES]( + rocacheline #(LINESIZE, TAGWIDTH, WORDSIZE) lines ( .*, .WriteEnable(WriteEnable & (WriteSet == i)), .WriteData(WriteLine), .WriteTag(WriteTag), .DataWord(LineOutputs[i]), .DataTag(TagOutputs[i]), - .DataValid(ValidOutputs[i]), + .DataValid(ValidOutputs[i]) ); end endgenerate diff --git a/wally-pipelined/src/cache/line.sv b/wally-pipelined/src/cache/line.sv index 85d4073bd..e498d0735 100644 --- a/wally-pipelined/src/cache/line.sv +++ b/wally-pipelined/src/cache/line.sv @@ -44,17 +44,25 @@ module rocacheline #(parameter LINESIZE = 256, parameter TAGSIZE = 32, parameter output logic DataValid ); - logic [LINESIZE-1:0] DataLine; - logic [$clog2(LINESIZE/8)-1:0] AlignedWordSelect; + 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); - flopenr #(LINESIZE) LineFlop(clk, reset, WriteEnable, WriteData, DataLine); + + 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 AlignedWordSelect = {WordSelect[$clog2(LINESIZE/8)-1:$clog2(WORDSIZE)], {$clog2(WORDSIZE){'b0}}}; - assign DataWord = DataLine[WORDSIZE+AlignedWordSelect-1:AlignedWordSelect]; + assign DataWord = DataLinesOut[WordSelect[OFFSETSIZE-1:$clog2(WORDSIZE)]]; end endmodule From 0776127c7590c4cf5d6ea402e5cbe562bfb692c7 Mon Sep 17 00:00:00 2001 From: Jarred Allen Date: Wed, 24 Mar 2021 12:31:01 -0400 Subject: [PATCH 30/41] Give some cache mem inputs a better name --- wally-pipelined/src/cache/dmapped.sv | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/wally-pipelined/src/cache/dmapped.sv b/wally-pipelined/src/cache/dmapped.sv index 52027b390..9a51737a6 100644 --- a/wally-pipelined/src/cache/dmapped.sv +++ b/wally-pipelined/src/cache/dmapped.sv @@ -5,6 +5,7 @@ // 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. // @@ -25,15 +26,15 @@ `include "wally-config.vh" -module rodirectmapped #(parameter LINESIZE = 256, parameter NUMLINES = 512, parameter WORDSIZE = `XLEN) ( +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] UpperPAdr, - input logic [11:0] LowerAdr, + 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, @@ -58,8 +59,8 @@ module rodirectmapped #(parameter LINESIZE = 256, parameter NUMLINES = 512, para // Swizzle bits to get the offset, set, and tag out of the read and write addresses always_comb begin // Read address - assign WordSelect = LowerAdr[OFFSETWIDTH-1:0]; - assign ReadPAdr = {UpperPAdr, LowerAdr}; + 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 @@ -89,3 +90,4 @@ module rodirectmapped #(parameter LINESIZE = 256, parameter NUMLINES = 512, para end endmodule + From 6edb055f26586077e1c6b3bbc68be31e0567c28b Mon Sep 17 00:00:00 2001 From: bbracker Date: Thu, 25 Mar 2021 00:44:35 -0400 Subject: [PATCH 31/41] instrfault direspecting stalls bugfix --- wally-pipelined/src/privileged/privileged.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wally-pipelined/src/privileged/privileged.sv b/wally-pipelined/src/privileged/privileged.sv index 8a6854e98..c967d2629 100644 --- a/wally-pipelined/src/privileged/privileged.sv +++ b/wally-pipelined/src/privileged/privileged.sv @@ -125,10 +125,10 @@ module privileged ( // pipeline fault signals flopenrc #(1) faultregD(clk, reset, FlushD, ~StallD, InstrAccessFaultF, InstrAccessFaultD); - floprc #(2) faultregE(clk, reset, FlushE, + flopenrc #(2) faultregE(clk, reset, FlushE, ~StallE, {IllegalIEUInstrFaultD, InstrAccessFaultD}, // ** vs IllegalInstrFaultInD {IllegalIEUInstrFaultE, InstrAccessFaultE}); - floprc #(2) faultregM(clk, reset, FlushM, + flopenrc #(2) faultregM(clk, reset, FlushM, ~StallM, {IllegalIEUInstrFaultE, InstrAccessFaultE}, {IllegalIEUInstrFaultM, InstrAccessFaultM}); From ca392225df31c58f30331ebf1344913e7f03db5a Mon Sep 17 00:00:00 2001 From: bbracker Date: Thu, 25 Mar 2021 02:15:28 -0400 Subject: [PATCH 32/41] added 1 tick delay on tim reads --- wally-pipelined/src/uncore/dtim.sv | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/wally-pipelined/src/uncore/dtim.sv b/wally-pipelined/src/uncore/dtim.sv index a5c4574ee..f96a14fbf 100644 --- a/wally-pipelined/src/uncore/dtim.sv +++ b/wally-pipelined/src/uncore/dtim.sv @@ -85,14 +85,14 @@ module dtim #(parameter BASE=0, RANGE = 65535) ( generate if (`XLEN == 64) begin always_ff @(posedge HCLK) begin - HWADDR <= A; - HREADTim0 <= RAM[A[31:3]]; + HWADDR <= #1 A; + HREADTim0 <= #1 RAM[A[31:3]]; if (memwrite && risingHREADYTim) RAM[HWADDR[31:3]] <= HWDATA; end end else begin always_ff @(posedge HCLK) begin - HWADDR <= A; - HREADTim0 <= RAM[A[31:2]]; + HWADDR <= #1 A; + HREADTim0 <= #1 RAM[A[31:2]]; if (memwrite && risingHREADYTim) RAM[HWADDR[31:2]] <= HWDATA; end end From abedaf62a83b4fe02199914ead6e392b5b8c4a86 Mon Sep 17 00:00:00 2001 From: Jarred Allen Date: Thu, 25 Mar 2021 12:42:48 -0400 Subject: [PATCH 33/41] Output NOP instead of BAD when reset --- wally-pipelined/src/ifu/icache.sv | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wally-pipelined/src/ifu/icache.sv b/wally-pipelined/src/ifu/icache.sv index 2eab6ed81..4208c3550 100644 --- a/wally-pipelined/src/ifu/icache.sv +++ b/wally-pipelined/src/ifu/icache.sv @@ -48,7 +48,7 @@ module icache( output logic [31:0] InstrRawD ); - logic DelayF, DelaySideF, FlushDLastCycle, DelayD; + logic DelayF, DelaySideF, FlushDLastCyclen, DelayD; logic [1:0] InstrDMuxChoice; logic [15:0] MisalignedHalfInstrF, MisalignedHalfInstrD; logic [31:0] InstrF, AlignedInstrD; @@ -65,7 +65,7 @@ module icache( // 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 | (FlushDLastCycle & StallF), FlushDLastCycle); + 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); @@ -127,7 +127,7 @@ module icache( // 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 (FlushDLastCycle) begin + always_comb if (~FlushDLastCyclen) begin assign InstrDMuxChoice = 2'b10; end else if (DelayD & (MisalignedHalfInstrD[1:0] != 2'b11)) begin assign InstrDMuxChoice = 2'b11; From 9eb1786fb13d410f916dd41734d00b0f55b0e8df Mon Sep 17 00:00:00 2001 From: Noah Boorstin Date: Thu, 25 Mar 2021 14:29:10 -0400 Subject: [PATCH 34/41] busybear: quick fix to mem reading also stop ignoring mcause at the start --- .../testbench/testbench-busybear.sv | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/wally-pipelined/testbench/testbench-busybear.sv b/wally-pipelined/testbench/testbench-busybear.sv index 254e672d8..71664a434 100644 --- a/wally-pipelined/testbench/testbench-busybear.sv +++ b/wally-pipelined/testbench/testbench-busybear.sv @@ -191,7 +191,7 @@ module testbench_busybear(); logic [`XLEN-1:0] readAdrExpected; always @(dut.HRDATA) begin - #1; + #2; if (dut.hart.MemRWM[1] && HADDR[31:3] != dut.PCF[31:3] && dut.HRDATA !== {64{1'bx}}) begin //$display("%0t", $time); if($feof(data_file_memR)) begin @@ -282,16 +282,14 @@ module testbench_busybear(); //CSR checking \ always @(``PATH``.``CSR``_REGW) begin \ if ($time > 1) begin \ - if (instrs > 1) begin \ - scan_file_csr = $fscanf(data_file_csr, "%s\n", CSR); \ - scan_file_csr = $fscanf(data_file_csr, "%x\n", expected``CSR``); \ - if(CSR.icompare(`"CSR`")) begin \ - $display("%0t ps, instr %0d: %s changed, expected %s", $time, instrs, `"CSR`", CSR); \ - end \ - if(``PATH``.``CSR``_REGW != ``expected``CSR) begin \ - $display("%0t ps, instr %0d: %s does not equal %s expected: %x, %x", $time, instrs, `"CSR`", CSR, ``PATH``.``CSR``_REGW, ``expected``CSR); \ - `ERROR \ - end \ + scan_file_csr = $fscanf(data_file_csr, "%s\n", CSR); \ + scan_file_csr = $fscanf(data_file_csr, "%x\n", expected``CSR``); \ + if(CSR.icompare(`"CSR`")) begin \ + $display("%0t ps, instr %0d: %s changed, expected %s", $time, instrs, `"CSR`", CSR); \ + end \ + if(``PATH``.``CSR``_REGW != ``expected``CSR) begin \ + $display("%0t ps, instr %0d: %s does not equal %s expected: %x, %x", $time, instrs, `"CSR`", CSR, ``PATH``.``CSR``_REGW, ``expected``CSR); \ + `ERROR \ end \ end else begin \ for(integer j=0; j Date: Fri, 26 Mar 2021 01:53:19 +0530 Subject: [PATCH 35/41] Removed PCW and InstrW from ifu --- wally-pipelined/regression/wally-busybear.do | 2 +- wally-pipelined/regression/wally-coremark.do | 6 +++--- wally-pipelined/regression/wally-coremark_bare.do | 6 +++--- wally-pipelined/regression/wave-all.do | 4 ++-- wally-pipelined/regression/wave-dos/ahb-waves.do | 4 ++-- wally-pipelined/regression/wave-dos/default-waves.do | 4 ++-- wally-pipelined/regression/wave.do | 2 +- wally-pipelined/src/ifu/ifu.sv | 8 ++++---- wally-pipelined/testbench/testbench-busybear.sv | 12 ++++++++---- wally-pipelined/testbench/testbench-coremark.sv | 8 +++++++- wally-pipelined/testbench/testbench-coremark_bare.sv | 10 +++++++++- wally-pipelined/testbench/testbench-imperas.sv | 8 +++++--- wally-pipelined/testbench/testbench-peripherals.sv | 4 +++- wally-pipelined/testbench/testbench-privileged.sv | 4 +++- 14 files changed, 53 insertions(+), 29 deletions(-) diff --git a/wally-pipelined/regression/wally-busybear.do b/wally-pipelined/regression/wally-busybear.do index e4b75a083..0f426d112 100644 --- a/wally-pipelined/regression/wally-busybear.do +++ b/wally-pipelined/regression/wally-busybear.do @@ -136,7 +136,7 @@ add wave /testbench_busybear/InstrMName #add wave -hex /testbench_busybear/dut/hart/dmem/AdrM #add wave -hex /testbench_busybear/dut/hart/dmem/WriteDataM #add wave -divider -add wave -hex /testbench_busybear/dut/hart/ifu/PCW +add wave -hex /testbench_busybear/PCW ##add wave -hex /testbench_busybear/dut/hart/ifu/InstrW add wave /testbench_busybear/InstrWName #add wave /testbench_busybear/dut/hart/ieu/dp/RegWriteW diff --git a/wally-pipelined/regression/wally-coremark.do b/wally-pipelined/regression/wally-coremark.do index ea63e2aec..5a309b78c 100644 --- a/wally-pipelined/regression/wally-coremark.do +++ b/wally-pipelined/regression/wally-coremark.do @@ -69,8 +69,8 @@ add wave -hex /testbench/dut/hart/ifu/PCM add wave -hex /testbench/dut/hart/ifu/InstrM add wave /testbench/InstrMName add wave -divider Write -add wave -hex /testbench/dut/hart/ifu/PCW -add wave -hex /testbench/dut/hart/ifu/InstrW +add wave -hex /testbench/PCW +add wave -hex /testbench/InstrW add wave /testbench/InstrWName #add wave -hex /testbench/dut/hart/ieu/dp/SrcAE #add wave -hex /testbench/dut/hart/ieu/dp/SrcBE @@ -81,7 +81,7 @@ add wave -divider Regfile_signals #add wave -hex /testbench/dut/uncore/HADDR #add wave -hex /testbench/dut/uncore/HWDATA #add wave -divider -#add wave -hex /testbench/dut/hart/ifu/PCW +#add wave -hex /testbench/PCW #add wave /testbench/InstrWName #add wave /testbench/dut/hart/ieu/dp/RegWriteW #add wave -hex /testbench/dut/hart/ieu/dp/ResultW diff --git a/wally-pipelined/regression/wally-coremark_bare.do b/wally-pipelined/regression/wally-coremark_bare.do index 63c2e64f9..9318c494a 100644 --- a/wally-pipelined/regression/wally-coremark_bare.do +++ b/wally-pipelined/regression/wally-coremark_bare.do @@ -69,8 +69,8 @@ add wave -hex /testbench/dut/hart/ifu/PCM add wave -hex /testbench/dut/hart/ifu/InstrM add wave /testbench/InstrMName add wave -divider Write -add wave -hex /testbench/dut/hart/ifu/PCW -add wave -hex /testbench/dut/hart/ifu/InstrW +add wave -hex /testbench/PCW +add wave -hex /testbench/InstrW add wave /testbench/InstrWName #add wave -hex /testbench/dut/hart/ieu/dp/SrcAE #add wave -hex /testbench/dut/hart/ieu/dp/SrcBE @@ -81,7 +81,7 @@ add wave -divider Regfile_signals #add wave -hex /testbench/dut/uncore/HADDR #add wave -hex /testbench/dut/uncore/HWDATA #add wave -divider -#add wave -hex /testbench/dut/hart/ifu/PCW +#add wave -hex /testbench/PCW #add wave /testbench/InstrWName #add wave /testbench/dut/hart/ieu/dp/RegWriteW #add wave -hex /testbench/dut/hart/ieu/dp/ResultW diff --git a/wally-pipelined/regression/wave-all.do b/wally-pipelined/regression/wave-all.do index a6a0747b8..cd2b453b4 100644 --- a/wally-pipelined/regression/wave-all.do +++ b/wally-pipelined/regression/wave-all.do @@ -45,7 +45,7 @@ add wave -noupdate /testbench/dut/uncore/dtim/memwrite add wave -noupdate -radix hexadecimal /testbench/dut/uncore/HADDR add wave -noupdate -radix hexadecimal /testbench/dut/uncore/HWDATA add wave -noupdate -divider -add wave -noupdate -radix hexadecimal /testbench/dut/hart/ifu/PCW +add wave -noupdate -radix hexadecimal /testbench/PCW add wave -noupdate /testbench/InstrWName add wave -noupdate /testbench/dut/hart/ieu/dp/RegWriteW add wave -noupdate -radix hexadecimal /testbench/dut/hart/ieu/dp/ResultW @@ -219,7 +219,7 @@ add wave -noupdate -radix hexadecimal /testbench/dut/hart/ifu/IllegalCompInstrD add wave -noupdate -radix hexadecimal /testbench/dut/hart/ifu/PCPlusUpperF add wave -noupdate -radix hexadecimal /testbench/dut/hart/ifu/PCPlus2or4F add wave -noupdate -radix hexadecimal /testbench/dut/hart/ifu/PCD -add wave -noupdate -radix hexadecimal /testbench/dut/hart/ifu/PCW +add wave -noupdate -radix hexadecimal /testbench/PCW add wave -noupdate -radix hexadecimal /testbench/dut/hart/ifu/PCLinkD add wave -noupdate -radix hexadecimal /testbench/dut/hart/ifu/PCLinkE add wave -noupdate -radix hexadecimal /testbench/dut/hart/ifu/PCLinkM diff --git a/wally-pipelined/regression/wave-dos/ahb-waves.do b/wally-pipelined/regression/wave-dos/ahb-waves.do index f24def65d..5101c757b 100644 --- a/wally-pipelined/regression/wave-dos/ahb-waves.do +++ b/wally-pipelined/regression/wave-dos/ahb-waves.do @@ -55,8 +55,8 @@ add wave -hex /testbench/dut/hart/ebu/CaptureDataM add wave -hex /testbench/dut/hart/ebu/InstrStall add wave -divider -add wave -hex /testbench/dut/hart/ifu/PCW -add wave -hex /testbench/dut/hart/ifu/InstrW +add wave -hex /testbench/PCW +add wave -hex /testbench/InstrW add wave /testbench/InstrWName add wave /testbench/dut/hart/ieu/dp/RegWriteW add wave -hex /testbench/dut/hart/ebu/ReadDataW diff --git a/wally-pipelined/regression/wave-dos/default-waves.do b/wally-pipelined/regression/wave-dos/default-waves.do index bdc9bf457..4b9214358 100644 --- a/wally-pipelined/regression/wave-dos/default-waves.do +++ b/wally-pipelined/regression/wave-dos/default-waves.do @@ -40,8 +40,8 @@ add wave /testbench/dut/uncore/dtim/memwrite add wave -hex /testbench/dut/uncore/HADDR add wave -hex /testbench/dut/uncore/HWDATA add wave -divider -add wave -hex /testbench/dut/hart/ifu/PCW -add wave -hex /testbench/dut/hart/ifu/InstrW +add wave -hex /testbench/PCW +add wave -hex /testbench/InstrW add wave /testbench/InstrWName add wave /testbench/dut/hart/ieu/dp/RegWriteW add wave -hex /testbench/dut/hart/ieu/dp/ResultW diff --git a/wally-pipelined/regression/wave.do b/wally-pipelined/regression/wave.do index 379c7ab49..c37729670 100644 --- a/wally-pipelined/regression/wave.do +++ b/wally-pipelined/regression/wave.do @@ -125,7 +125,7 @@ add wave -noupdate -expand -group PCS /testbench/dut/hart/PCF add wave -noupdate -expand -group PCS /testbench/dut/hart/ifu/PCD add wave -noupdate -expand -group PCS /testbench/dut/hart/PCE add wave -noupdate -expand -group PCS /testbench/dut/hart/PCM -add wave -noupdate -expand -group PCS /testbench/dut/hart/ifu/PCW +add wave -noupdate -expand -group PCS /testbench/PCW add wave -noupdate -group {function radix debug} /testbench/functionRadix/function_radix/FunctionAddr add wave -noupdate -group {function radix debug} -radix unsigned /testbench/functionRadix/function_radix/ProgramAddrIndex add wave -noupdate -group {function radix debug} /testbench/functionRadix/function_radix/reset diff --git a/wally-pipelined/src/ifu/ifu.sv b/wally-pipelined/src/ifu/ifu.sv index eb65e1679..c869aa2c9 100644 --- a/wally-pipelined/src/ifu/ifu.sv +++ b/wally-pipelined/src/ifu/ifu.sv @@ -71,9 +71,9 @@ module ifu ( logic misaligned, BranchMisalignedFaultE, BranchMisalignedFaultM, TrapMisalignedFaultM; logic PrivilegedChangePCM; logic IllegalCompInstrD; - logic [`XLEN-1:0] PCPlusUpperF, PCPlus2or4F, PCD, PCW, PCLinkD, PCLinkM; + logic [`XLEN-1:0] PCPlusUpperF, PCPlus2or4F, PCD, PCLinkD, PCLinkM; logic CompressedF; - logic [31:0] InstrF, InstrRawD, InstrE, InstrW; + logic [31:0] InstrF, InstrRawD, InstrE; logic [31:0] nop = 32'h00000013; // instruction for NOP // *** temporary hack until walker is hooked up -- Thomas F @@ -196,10 +196,10 @@ module ifu ( flopenr #(32) InstrEReg(clk, reset, ~StallE, FlushE ? nop : InstrD, InstrE); flopenr #(32) InstrMReg(clk, reset, ~StallM, FlushM ? nop : InstrE, InstrM); - flopenr #(32) InstrWReg(clk, reset, ~StallW, FlushW ? nop : InstrM, InstrW); // just for testbench, delete later + // flopenr #(32) InstrWReg(clk, reset, ~StallW, FlushW ? nop : InstrM, InstrW); // just for testbench, delete later flopenr #(`XLEN) PCEReg(clk, reset, ~StallE, PCD, PCE); flopenr #(`XLEN) PCMReg(clk, reset, ~StallM, PCE, PCM); - flopenr #(`XLEN) PCWReg(clk, reset, ~StallW, PCM, PCW); // *** probably not needed; delete later + // flopenr #(`XLEN) PCWReg(clk, reset, ~StallW, PCM, PCW); // *** probably not needed; delete later flopenrc #(4) InstrClassRegE(.clk(clk), .reset(reset), diff --git a/wally-pipelined/testbench/testbench-busybear.sv b/wally-pipelined/testbench/testbench-busybear.sv index 6f957efa3..ff23d0512 100644 --- a/wally-pipelined/testbench/testbench-busybear.sv +++ b/wally-pipelined/testbench/testbench-busybear.sv @@ -143,6 +143,9 @@ module testbench_busybear(); logic [63:0] pcExpected; logic [63:0] regExpected; integer regNumExpected; + logic [`XLEN-1:0] PCW; + + flopenr #(`XLEN) PCWReg(clk, reset, ~StallW, dut.hart.ifu.PCM, PCW); genvar i; generate @@ -349,8 +352,8 @@ module testbench_busybear(); string PCtextW, PCtext2W; logic [31:0] InstrWExpected; logic [63:0] PCWExpected; - always @(dut.hart.ifu.PCW or dut.hart.ieu.InstrValidW) begin - if(dut.hart.ieu.InstrValidW && dut.hart.ifu.PCW != 0) begin + always @(PCW or dut.hart.ieu.InstrValidW) begin + if(dut.hart.ieu.InstrValidW && PCW != 0) begin if($feof(data_file_PCW)) begin $display("no more PC data to read"); `ERROR @@ -363,8 +366,8 @@ module testbench_busybear(); scan_file_PCW = $fscanf(data_file_PCW, "%x\n", InstrWExpected); // then expected PC value scan_file_PCW = $fscanf(data_file_PCW, "%x\n", PCWExpected); - if(~equal(dut.hart.ifu.PCW,PCWExpected,2)) begin - $display("%0t ps, instr %0d: PCW does not equal PCW expected: %x, %x", $time, instrs, dut.hart.ifu.PCW, PCWExpected); + if(~equal(PCW,PCWExpected,2)) begin + $display("%0t ps, instr %0d: PCW does not equal PCW expected: %x, %x", $time, instrs, PCW, PCWExpected); `ERROR end //if(it.InstrW != InstrWExpected) begin @@ -505,6 +508,7 @@ module testbench_busybear(); // Track names of instructions string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName; logic [31:0] InstrW; + flopenr #(32) InstrWReg(clk, reset, ~dut.hart.hazard.StallW, dut.hart.hazard.FlushW ? nop : dut.hart.ifu.InstrM, InstrW); instrNameDecTB dec(dut.hart.ifu.InstrF, InstrFName); instrTrackerTB it(clk, reset, dut.hart.ieu.dp.FlushE, dut.hart.ifu.InstrD, dut.hart.ifu.InstrE, diff --git a/wally-pipelined/testbench/testbench-coremark.sv b/wally-pipelined/testbench/testbench-coremark.sv index fbec9f46e..44c31f71a 100644 --- a/wally-pipelined/testbench/testbench-coremark.sv +++ b/wally-pipelined/testbench/testbench-coremark.sv @@ -60,12 +60,18 @@ module testbench(); assign HRDATAEXT = 0; wallypipelinedsoc dut(.*); // Track names of instructions + logic [31:0] InstrW; + flopenr #(32) InstrWReg(clk, reset, ~dut.hart.hazard.StallW, dut.hart.hazard.FlushW ? nop : dut.hart.ifu.InstrM, InstrW); instrTrackerTB it(clk, reset, dut.hart.ieu.dp.FlushE, dut.hart.ifu.InstrF, dut.hart.ifu.InstrD, dut.hart.ifu.InstrE, - dut.hart.ifu.InstrM, dut.hart.ifu.InstrW, + dut.hart.ifu.InstrM, InstrW, InstrFName, InstrDName, InstrEName, InstrMName, InstrWName); // initialize tests + + logic [`XLEN-1:0] PCW; + flopenr #(`XLEN) PCWReg(clk, reset, ~StallW, dut.hart.ifu.PCM, PCW); + integer j; initial begin diff --git a/wally-pipelined/testbench/testbench-coremark_bare.sv b/wally-pipelined/testbench/testbench-coremark_bare.sv index 0035450da..9018df092 100644 --- a/wally-pipelined/testbench/testbench-coremark_bare.sv +++ b/wally-pipelined/testbench/testbench-coremark_bare.sv @@ -59,12 +59,20 @@ module testbench(); assign HRESPEXT = 0; assign HRDATAEXT = 0; wallypipelinedsoc dut(.*); + + logic [31:0] InstrW; + flopenr #(32) InstrWReg(clk, reset, ~dut.hart.hazard.StallW, dut.hart.hazard.FlushW ? nop : dut.hart.ifu.InstrM, InstrW); + // Track names of instructions instrTrackerTB it(clk, reset, dut.hart.ieu.dp.FlushE, dut.hart.ifu.InstrF, dut.hart.ifu.InstrD, dut.hart.ifu.InstrE, - dut.hart.ifu.InstrM, dut.hart.ifu.InstrW, + dut.hart.ifu.InstrM, InstrW, InstrFName, InstrDName, InstrEName, InstrMName, InstrWName); + + logic [`XLEN-1:0] PCW; + flopenr #(`XLEN) PCWReg(clk, reset, ~StallW, dut.hart.ifu.PCM, PCW); + // initialize tests integer j; initial diff --git a/wally-pipelined/testbench/testbench-imperas.sv b/wally-pipelined/testbench/testbench-imperas.sv index 2f6f0efbc..fd5eea646 100644 --- a/wally-pipelined/testbench/testbench-imperas.sv +++ b/wally-pipelined/testbench/testbench-imperas.sv @@ -38,7 +38,7 @@ module testbench(); logic [`XLEN-1:0] signature[0:10000]; logic [`XLEN-1:0] testadr; string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName; - //logic [31:0] InstrW; + logic [31:0] InstrW; logic [`XLEN-1:0] meminit; string tests64a[] = '{ "rv64a/WALLY-AMO", "2110", @@ -332,8 +332,10 @@ string tests32i[] = { logic [1:0] HTRANS; logic HMASTLOCK; logic HCLK, HRESETn; - + logic [`XLEN-1:0] PCW; + flopenr #(`XLEN) PCWReg(clk, reset, ~dut.hart.hazard.StallW, dut.hart.ifu.PCM, PCW); + flopenr #(32) InstrWReg(clk, reset, ~dut.hart.hazard.StallW, dut.hart.hazard.FlushW ? nop : dut.hart.ifu.InstrM, InstrW); // pick tests based on modes supported initial if (`XLEN == 64) begin // RV64 @@ -372,7 +374,7 @@ string tests32i[] = { // Track names of instructions instrTrackerTB it(clk, reset, dut.hart.ieu.dp.FlushE, dut.hart.ifu.InstrF, dut.hart.ifu.InstrD, dut.hart.ifu.InstrE, - dut.hart.ifu.InstrM, dut.hart.ifu.InstrW, + dut.hart.ifu.InstrM, InstrW, InstrFName, InstrDName, InstrEName, InstrMName, InstrWName); // initialize tests diff --git a/wally-pipelined/testbench/testbench-peripherals.sv b/wally-pipelined/testbench/testbench-peripherals.sv index ba4b94fae..3a4ea3b14 100644 --- a/wally-pipelined/testbench/testbench-peripherals.sv +++ b/wally-pipelined/testbench/testbench-peripherals.sv @@ -73,13 +73,15 @@ module testbench(); assign HRDATAEXT = 0; wallypipelinedsoc dut(.*); - + flopenr #(32) InstrWReg(clk, reset, ~dut.hart.hazard.StallW, dut.hart.hazard.FlushW ? nop : dut.hart.ifu.InstrM, InstrW); // Track names of instructions instrTrackerTB it(clk, reset, dut.hart.ieu.dp.FlushE, dut.hart.ifu.InstrD, dut.hart.ifu.InstrE, dut.hart.ifu.InstrM, InstrW, InstrDName, InstrEName, InstrMName, InstrWName); + logic [`XLEN-1:0] PCW; + flopenr #(`XLEN) PCWReg(clk, reset, ~StallW, dut.hart.ifu.PCM, PCW); // initialize tests initial begin diff --git a/wally-pipelined/testbench/testbench-privileged.sv b/wally-pipelined/testbench/testbench-privileged.sv index 999604480..6785f7026 100644 --- a/wally-pipelined/testbench/testbench-privileged.sv +++ b/wally-pipelined/testbench/testbench-privileged.sv @@ -73,13 +73,15 @@ module testbench(); assign HRDATAEXT = 0; wallypipelinedsoc dut(.*); - + flopenr #(32) InstrWReg(clk, reset, ~dut.hart.hazard.StallW, dut.hart.hazard.FlushW ? nop : dut.hart.ifu.InstrM, InstrW); // Track names of instructions instrTrackerTB it(clk, reset, dut.hart.ieu.dp.FlushE, dut.hart.ifu.InstrD, dut.hart.ifu.InstrE, dut.hart.ifu.InstrM, InstrW, InstrDName, InstrEName, InstrMName, InstrWName); + logic [`XLEN-1:0] PCW; + flopenr #(`XLEN) PCWReg(clk, reset, ~StallW, dut.hart.ifu.PCM, PCW); // initialize tests initial begin From d3e914f64ba01f00ab3d557a94237e9da619ce9b Mon Sep 17 00:00:00 2001 From: Shreya Sanghai Date: Thu, 25 Mar 2021 20:29:50 -0400 Subject: [PATCH 36/41] removed minor bugs --- .../testbench/testbench-busybear.sv | 127 +++++++++++++++++- .../testbench/testbench-coremark.sv | 2 +- .../testbench/testbench-coremark_bare.sv | 2 +- .../testbench/testbench-imperas.sv | 4 +- .../testbench/testbench-peripherals.sv | 4 +- .../testbench/testbench-privileged.sv | 4 +- 6 files changed, 134 insertions(+), 9 deletions(-) diff --git a/wally-pipelined/testbench/testbench-busybear.sv b/wally-pipelined/testbench/testbench-busybear.sv index ff23d0512..dd9305a12 100644 --- a/wally-pipelined/testbench/testbench-busybear.sv +++ b/wally-pipelined/testbench/testbench-busybear.sv @@ -508,7 +508,7 @@ module testbench_busybear(); // Track names of instructions string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName; logic [31:0] InstrW; - flopenr #(32) InstrWReg(clk, reset, ~dut.hart.hazard.StallW, dut.hart.hazard.FlushW ? nop : 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); instrTrackerTB it(clk, reset, dut.hart.ieu.dp.FlushE, dut.hart.ifu.InstrD, dut.hart.ifu.InstrE, @@ -522,3 +522,128 @@ module testbench_busybear(); end endmodule +module instrTrackerTB( + input logic clk, reset, FlushE, + input logic [31:0] InstrD, + input logic [31:0] InstrE, InstrM, + output logic [31:0] InstrW, + output string InstrDName, InstrEName, InstrMName, InstrWName); + + // stage Instr to Writeback for visualization + //flopr #(32) InstrWReg(clk, reset, InstrM, InstrW); + + instrNameDecTB ddec(InstrD, InstrDName); + instrNameDecTB edec(InstrE, InstrEName); + instrNameDecTB mdec(InstrM, InstrMName); + instrNameDecTB wdec(InstrW, InstrWName); +endmodule + +// decode the instruction name, to help the test bench +module instrNameDecTB( + input logic [31:0] instr, + output string name); + + logic [6:0] op; + logic [2:0] funct3; + logic [6:0] funct7; + logic [11:0] imm; + + assign op = instr[6:0]; + assign funct3 = instr[14:12]; + assign funct7 = instr[31:25]; + assign imm = instr[31:20]; + + // it would be nice to add the operands to the name + // create another variable called decoded + + always_comb + casez({op, funct3}) + 10'b0000000_000: name = "BAD"; + 10'b0000011_000: name = "LB"; + 10'b0000011_001: name = "LH"; + 10'b0000011_010: name = "LW"; + 10'b0000011_011: name = "LD"; + 10'b0000011_100: name = "LBU"; + 10'b0000011_101: name = "LHU"; + 10'b0000011_110: name = "LWU"; + 10'b0010011_000: if (instr[31:15] == 0 && instr[11:7] ==0) name = "NOP/FLUSH"; + else name = "ADDI"; + 10'b0010011_001: if (funct7[6:1] == 6'b000000) name = "SLLI"; + else name = "ILLEGAL"; + 10'b0010011_010: name = "SLTI"; + 10'b0010011_011: name = "SLTIU"; + 10'b0010011_100: name = "XORI"; + 10'b0010011_101: if (funct7[6:1] == 6'b000000) name = "SRLI"; + else if (funct7[6:1] == 6'b010000) name = "SRAI"; + else name = "ILLEGAL"; + 10'b0010011_110: name = "ORI"; + 10'b0010011_111: name = "ANDI"; + 10'b0010111_???: name = "AUIPC"; + 10'b0100011_000: name = "SB"; + 10'b0100011_001: name = "SH"; + 10'b0100011_010: name = "SW"; + 10'b0100011_011: name = "SD"; + 10'b0011011_000: name = "ADDIW"; + 10'b0011011_001: name = "SLLIW"; + 10'b0011011_101: if (funct7 == 7'b0000000) name = "SRLIW"; + else if (funct7 == 7'b0100000) name = "SRAIW"; + else name = "ILLEGAL"; + 10'b0111011_000: if (funct7 == 7'b0000000) name = "ADDW"; + else if (funct7 == 7'b0100000) name = "SUBW"; + else name = "ILLEGAL"; + 10'b0111011_001: name = "SLLW"; + 10'b0111011_101: if (funct7 == 7'b0000000) name = "SRLW"; + else if (funct7 == 7'b0100000) name = "SRAW"; + else name = "ILLEGAL"; + 10'b0110011_000: if (funct7 == 7'b0000000) name = "ADD"; + else if (funct7 == 7'b0000001) name = "MUL"; + else if (funct7 == 7'b0100000) name = "SUB"; + else name = "ILLEGAL"; + 10'b0110011_001: if (funct7 == 7'b0000000) name = "SLL"; + else if (funct7 == 7'b0000001) name = "MULH"; + else name = "ILLEGAL"; + 10'b0110011_010: if (funct7 == 7'b0000000) name = "SLT"; + else if (funct7 == 7'b0000001) name = "MULHSU"; + else name = "ILLEGAL"; + 10'b0110011_011: if (funct7 == 7'b0000000) name = "SLTU"; + else if (funct7 == 7'b0000001) name = "DIV"; + else name = "ILLEGAL"; + 10'b0110011_100: if (funct7 == 7'b0000000) name = "XOR"; + else if (funct7 == 7'b0000001) name = "MUL"; + else name = "ILLEGAL"; + 10'b0110011_101: if (funct7 == 7'b0000000) name = "SRL"; + else if (funct7 == 7'b0000001) name = "DIVU"; + else if (funct7 == 7'b0100000) name = "SRA"; + else name = "ILLEGAL"; + 10'b0110011_110: if (funct7 == 7'b0000000) name = "OR"; + else if (funct7 == 7'b0000001) name = "REM"; + else name = "ILLEGAL"; + 10'b0110011_111: if (funct7 == 7'b0000000) name = "AND"; + else if (funct7 == 7'b0000001) name = "REMU"; + else name = "ILLEGAL"; + 10'b0110111_???: name = "LUI"; + 10'b1100011_000: name = "BEQ"; + 10'b1100011_001: name = "BNE"; + 10'b1100011_100: name = "BLT"; + 10'b1100011_101: name = "BGE"; + 10'b1100011_110: name = "BLTU"; + 10'b1100011_111: name = "BGEU"; + 10'b1100111_000: name = "JALR"; + 10'b1101111_???: name = "JAL"; + 10'b1110011_000: if (imm == 0) name = "ECALL"; + else if (imm == 1) name = "EBREAK"; + else if (imm == 2) name = "URET"; + else if (imm == 258) name = "SRET"; + else if (imm == 770) name = "MRET"; + else name = "ILLEGAL"; + 10'b1110011_001: name = "CSRRW"; + 10'b1110011_010: name = "CSRRS"; + 10'b1110011_011: name = "CSRRC"; + 10'b1110011_101: name = "CSRRWI"; + 10'b1110011_110: name = "CSRRSI"; + 10'b1110011_111: name = "CSRRCI"; + 10'b0001111_???: name = "FENCE"; + default: name = "ILLEGAL"; + endcase +endmodule + diff --git a/wally-pipelined/testbench/testbench-coremark.sv b/wally-pipelined/testbench/testbench-coremark.sv index 44c31f71a..eae3ebdcf 100644 --- a/wally-pipelined/testbench/testbench-coremark.sv +++ b/wally-pipelined/testbench/testbench-coremark.sv @@ -61,7 +61,7 @@ module testbench(); wallypipelinedsoc dut(.*); // Track names of instructions logic [31:0] InstrW; - flopenr #(32) InstrWReg(clk, reset, ~dut.hart.hazard.StallW, dut.hart.hazard.FlushW ? nop : dut.hart.ifu.InstrM, InstrW); + flopenr #(32) InstrWReg(clk, reset, ~dut.hart.ieu.dp.StallW, dut.hart.ifu.InstrM, InstrW); instrTrackerTB it(clk, reset, dut.hart.ieu.dp.FlushE, dut.hart.ifu.InstrF, dut.hart.ifu.InstrD, dut.hart.ifu.InstrE, diff --git a/wally-pipelined/testbench/testbench-coremark_bare.sv b/wally-pipelined/testbench/testbench-coremark_bare.sv index 9018df092..127855393 100644 --- a/wally-pipelined/testbench/testbench-coremark_bare.sv +++ b/wally-pipelined/testbench/testbench-coremark_bare.sv @@ -61,7 +61,7 @@ module testbench(); wallypipelinedsoc dut(.*); logic [31:0] InstrW; - flopenr #(32) InstrWReg(clk, reset, ~dut.hart.hazard.StallW, dut.hart.hazard.FlushW ? nop : dut.hart.ifu.InstrM, InstrW); + flopenr #(32) InstrWReg(clk, reset, ~dut.hart.ieu.dp.StallW, dut.hart.ifu.InstrM, InstrW); // Track names of instructions instrTrackerTB it(clk, reset, dut.hart.ieu.dp.FlushE, diff --git a/wally-pipelined/testbench/testbench-imperas.sv b/wally-pipelined/testbench/testbench-imperas.sv index fd5eea646..f46259490 100644 --- a/wally-pipelined/testbench/testbench-imperas.sv +++ b/wally-pipelined/testbench/testbench-imperas.sv @@ -334,8 +334,8 @@ string tests32i[] = { logic HCLK, HRESETn; logic [`XLEN-1:0] PCW; - flopenr #(`XLEN) PCWReg(clk, reset, ~dut.hart.hazard.StallW, dut.hart.ifu.PCM, PCW); - flopenr #(32) InstrWReg(clk, reset, ~dut.hart.hazard.StallW, dut.hart.hazard.FlushW ? nop : dut.hart.ifu.InstrM, InstrW); + flopenr #(`XLEN) PCWReg(clk, reset, ~dut.hart.ieu.dp.StallW, dut.hart.ifu.PCM, PCW); + flopenr #(32) InstrWReg(clk, reset, ~dut.hart.ieu.dp.StallW, dut.hart.ifu.InstrM, InstrW); // pick tests based on modes supported initial if (`XLEN == 64) begin // RV64 diff --git a/wally-pipelined/testbench/testbench-peripherals.sv b/wally-pipelined/testbench/testbench-peripherals.sv index 3a4ea3b14..9067fede1 100644 --- a/wally-pipelined/testbench/testbench-peripherals.sv +++ b/wally-pipelined/testbench/testbench-peripherals.sv @@ -73,7 +73,7 @@ module testbench(); assign HRDATAEXT = 0; wallypipelinedsoc dut(.*); - flopenr #(32) InstrWReg(clk, reset, ~dut.hart.hazard.StallW, dut.hart.hazard.FlushW ? nop : dut.hart.ifu.InstrM, InstrW); + flopenr #(32) InstrWReg(clk, reset, ~dut.hart.ieu.dp.StallW, dut.hart.ifu.InstrM, InstrW); // Track names of instructions instrTrackerTB it(clk, reset, dut.hart.ieu.dp.FlushE, dut.hart.ifu.InstrD, dut.hart.ifu.InstrE, @@ -189,7 +189,7 @@ module instrTrackerTB( output string InstrDName, InstrEName, InstrMName, InstrWName); // stage Instr to Writeback for visualization - flopr #(32) InstrWReg(clk, reset, InstrM, InstrW); + //flopr #(32) InstrWReg(clk, reset, InstrM, InstrW); instrNameDecTB ddec(InstrD, InstrDName); instrNameDecTB edec(InstrE, InstrEName); diff --git a/wally-pipelined/testbench/testbench-privileged.sv b/wally-pipelined/testbench/testbench-privileged.sv index 6785f7026..ab6fe162d 100644 --- a/wally-pipelined/testbench/testbench-privileged.sv +++ b/wally-pipelined/testbench/testbench-privileged.sv @@ -73,7 +73,7 @@ module testbench(); assign HRDATAEXT = 0; wallypipelinedsoc dut(.*); - flopenr #(32) InstrWReg(clk, reset, ~dut.hart.hazard.StallW, dut.hart.hazard.FlushW ? nop : dut.hart.ifu.InstrM, InstrW); + flopenr #(32) InstrWReg(clk, reset, ~dut.hart.ieu.dp.StallW, dut.hart.ifu.InstrM, InstrW); // Track names of instructions instrTrackerTB it(clk, reset, dut.hart.ieu.dp.FlushE, dut.hart.ifu.InstrD, dut.hart.ifu.InstrE, @@ -189,7 +189,7 @@ module instrTrackerTB( output string InstrDName, InstrEName, InstrMName, InstrWName); // stage Instr to Writeback for visualization - flopr #(32) InstrWReg(clk, reset, InstrM, InstrW); + //flopr #(32) InstrWReg(clk, reset, InstrM, InstrW); instrNameDecTB ddec(InstrD, InstrDName); instrNameDecTB edec(InstrE, InstrEName); From aa0d0d50d86c14d2517828a0eaefa57a950f503f Mon Sep 17 00:00:00 2001 From: David Harris Date: Fri, 26 Mar 2021 13:03:23 -0400 Subject: [PATCH 37/41] Added fp test to testbench --- .../testbench/testbench-imperas.sv | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/wally-pipelined/testbench/testbench-imperas.sv b/wally-pipelined/testbench/testbench-imperas.sv index 2f6f0efbc..c5a49d6d0 100644 --- a/wally-pipelined/testbench/testbench-imperas.sv +++ b/wally-pipelined/testbench/testbench-imperas.sv @@ -40,6 +40,11 @@ module testbench(); string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName; //logic [31:0] InstrW; logic [`XLEN-1:0] meminit; + string tests64f[] = '{ + "rv64f/I-FADD-S-01", "2000", + "rv64f/I-FCLASS-S-01", "2000" + }; + string tests64a[] = '{ "rv64a/WALLY-AMO", "2110", "rv64a/WALLY-LRSC", "2110" @@ -337,14 +342,16 @@ string tests32i[] = { // pick tests based on modes supported initial if (`XLEN == 64) begin // RV64 - if(TESTSBP) begin - tests = testsBP64; + if (TESTSBP) begin + tests = testsBP64; end else begin - tests = {tests64i}; - if (`C_SUPPORTED) tests = {tests, tests64ic}; - else tests = {tests, tests64iNOc}; - if (`M_SUPPORTED) tests = {tests, tests64m}; - if (`A_SUPPORTED) tests = {tests, tests64a}; + tests = {tests64i}; + if (`C_SUPPORTED) tests = {tests, tests64ic}; + else tests = {tests, tests64iNOc}; + if (`M_SUPPORTED) tests = {tests, tests64m}; + if (`F_SUPPORTED) tests = {tests64f, tests}; + if (`D_SUPPORTED) tests = {tests64d, tests}; + if (`A_SUPPORTED) tests = {tests, tests64a}; end // tests = {tests64a, tests}; end else begin // RV32 @@ -353,6 +360,7 @@ string tests32i[] = { if (`C_SUPPORTED % 2 == 1) tests = {tests, tests32ic}; else tests = {tests, tests32iNOc}; if (`M_SUPPORTED % 2 == 1) tests = {tests, tests32m}; + if (`F_SUPPORTED) tests = {tests32f, tests}; if (`A_SUPPORTED) tests = {tests, tests32a}; end string signame, memfilename; From dd0b3fde5982fb356704ca96bb83efcf4538e849 Mon Sep 17 00:00:00 2001 From: Jarred Allen Date: Tue, 30 Mar 2021 13:07:26 -0400 Subject: [PATCH 39/41] Comment out failing tests --- wally-pipelined/testbench/testbench-imperas.sv | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wally-pipelined/testbench/testbench-imperas.sv b/wally-pipelined/testbench/testbench-imperas.sv index c312c7457..71457d1f0 100644 --- a/wally-pipelined/testbench/testbench-imperas.sv +++ b/wally-pipelined/testbench/testbench-imperas.sv @@ -350,8 +350,8 @@ string tests32i[] = { if (`C_SUPPORTED) tests = {tests, tests64ic}; else tests = {tests, tests64iNOc}; if (`M_SUPPORTED) tests = {tests, tests64m}; - if (`F_SUPPORTED) tests = {tests64f, tests}; - if (`D_SUPPORTED) tests = {tests64d, tests}; + // if (`F_SUPPORTED) tests = {tests64f, tests}; + // if (`D_SUPPORTED) tests = {tests64d, tests}; if (`A_SUPPORTED) tests = {tests, tests64a}; end // tests = {tests64a, tests}; @@ -361,7 +361,7 @@ string tests32i[] = { if (`C_SUPPORTED % 2 == 1) tests = {tests, tests32ic}; else tests = {tests, tests32iNOc}; if (`M_SUPPORTED % 2 == 1) tests = {tests, tests32m}; - if (`F_SUPPORTED) tests = {tests32f, tests}; + // if (`F_SUPPORTED) tests = {tests32f, tests}; if (`A_SUPPORTED) tests = {tests, tests32a}; end string signame, memfilename; From f4a533b6f687d51df215f8b16d8168de1541b34a Mon Sep 17 00:00:00 2001 From: "James E. Stine" Date: Tue, 30 Mar 2021 14:21:02 -0500 Subject: [PATCH 40/41] Initial push of rv64imc and appropriate testbench --- wally-pipelined/regression/run_sim.sh | 3 + .../regression/sim-wally-batch-muldiv | 3 + .../wally-pipelined-batch-muldiv.do | 43 +++++++++++ wally-pipelined/regression/wave-osu.do | 75 +++++++++++++++++++ 4 files changed, 124 insertions(+) create mode 100755 wally-pipelined/regression/run_sim.sh create mode 100755 wally-pipelined/regression/sim-wally-batch-muldiv create mode 100644 wally-pipelined/regression/wally-pipelined-batch-muldiv.do create mode 100755 wally-pipelined/regression/wave-osu.do diff --git a/wally-pipelined/regression/run_sim.sh b/wally-pipelined/regression/run_sim.sh new file mode 100755 index 000000000..6e52eb405 --- /dev/null +++ b/wally-pipelined/regression/run_sim.sh @@ -0,0 +1,3 @@ +#!/bin/sh +vsim -do $1 + diff --git a/wally-pipelined/regression/sim-wally-batch-muldiv b/wally-pipelined/regression/sim-wally-batch-muldiv new file mode 100755 index 000000000..c9db7ed18 --- /dev/null +++ b/wally-pipelined/regression/sim-wally-batch-muldiv @@ -0,0 +1,3 @@ +vsim -c <" prompt: +# do wally-pipelined-batch.do +# or, to run from a shell, type the following at the shell prompt: +# vsim -do wally-pipelined-batch.do -c +# (omit the "-c" to see the GUI while running from the shell) + +onbreak {resume} + +# create library +if [file exists work_$2] { + vdel -lib work_$2 -all +} +vlib work_$2 + +# compile source files +# suppress spurious warnngs about +# "Extra checking for conflicts with always_comb done at vopt time" +# because vsim will run vopt + +# default to config/rv64ic, but allow this to be overridden at the command line. For example: +# do wally-pipelined-batch.do ../config/rv32ic rv32ic +switch $argc { + 0 {vlog +incdir+../config/rv64imc ../testbench/testbench-imperas.sv ../src/*/*.sv -suppress 2583} + 1 {vlog +incdir+$1 ../testbench/testbench-imperas.sv ../src/*/*.sv -suppress 2583} + 2 {vlog -work work_$2 +incdir+$1 ../testbench/testbench-imperas.sv ../src/*/*.sv -suppress 2583} +} +# start and run simulation +# remove +acc flag for faster sim during regressions if there is no need to access internal signals +vopt work_$2.testbench -work work_$2 -o workopt_$2 +vsim -lib work_$2 workopt_$2 + +run -all +quit diff --git a/wally-pipelined/regression/wave-osu.do b/wally-pipelined/regression/wave-osu.do new file mode 100755 index 000000000..218bc7391 --- /dev/null +++ b/wally-pipelined/regression/wave-osu.do @@ -0,0 +1,75 @@ +# wally-pipelined.do +# +# Modification by Oklahoma State University & Harvey Mudd College +# Use with Testbench +# James Stine, 2008; David Harris 2021 +# Go Cowboys!!!!!! +# +# Takes 1:10 to run RV64IC tests using gui + +# Use this wally-pipelined.do file to run this example. +# Either bring up ModelSim and type the following at the "ModelSim>" prompt: +# do wally-pipelined.do +# or, to run from a shell, type the following at the shell prompt: +# vsim -do wally-pipelined.do -c +# (omit the "-c" to see the GUI while running from the shell) + +onbreak {resume} + +# create library +if [file exists work] { + vdel -all +} +vlib work + +# compile source files +# suppress spurious warnngs about +# "Extra checking for conflicts with always_comb done at vopt time" +# because vsim will run vopt + +# default to config/rv64ic, but allow this to be overridden at the command line. For example: +# do wally-pipelined.do ../config/rv32ic +switch $argc { + 0 {vlog +incdir+../config/rv64ic ../testbench/testbench-imperas.sv ../src/*/*.sv -suppress 2583} + 1 {vlog +incdir+$1 ../testbench/testbench-imperas.sv ../src/*/*.sv -suppress 2583} +} +# start and run simulation +# remove +acc flag for faster sim during regressions if there is no need to access internal signals +vopt +acc work.testbench -o workopt +vsim workopt + +view wave + +-- display input and output signals as hexidecimal values +# Diplays All Signals recursively +-- display input and output signals as hexidecimal values +# Diplays All Signals recursively +add wave /testbench/clk +add wave /testbench/reset +add wave -noupdate -divider -height 32 "Datapath" +add wave -hex /testbench/dut/hart/ieu/dp/* +add wave -noupdate -divider -height 32 "RF" +add wave -hex /testbench/dut/hart/ieu/dp/regf/* +add wave -hex /testbench/dut/hart/ieu/dp/regf/rf +add wave -noupdate -divider -height 32 "Control" +add wave -hex /testbench/dut/hart/ieu/c/* +add wave -noupdate -divider -height 32 "Multiply/Divide" +add wave -hex /testbench/dut/hart/mdu/* + +-- Set Wave Output Items +TreeUpdate [SetDefaultTree] +WaveRestoreZoom {0 ps} {100 ps} +configure wave -namecolwidth 250 +configure wave -valuecolwidth 120 +configure wave -justifyvalue left +configure wave -signalnamewidth 0 +configure wave -snapdistance 10 +configure wave -datasetprefix 0 +configure wave -rowmargin 4 +configure wave -childrowmargin 2 +set DefaultRadix hexadecimal + +-- Run the Simulation +#run 1000 +run -all +#quit From b2039e5b9a98c672fe1c01e3cc5a7f05f0017043 Mon Sep 17 00:00:00 2001 From: "James E. Stine" Date: Tue, 30 Mar 2021 14:21:45 -0500 Subject: [PATCH 41/41] Second update to divide that didn't get in for some silly git reason --- .../config/rv64imc/BTBPredictor.txt | 1024 +++++++++ .../config/rv64imc/twoBitPredictor.txt | 1024 +++++++++ .../config/rv64imc/wally-config.vh | 100 + .../config/rv64imc/wally-constants.vh | 31 + wally-pipelined/src/ieu/forward.sv | 15 +- wally-pipelined/src/ieu/ieu.sv | 46 +- wally-pipelined/src/ifu/ifu.sv | 2 +- wally-pipelined/src/muldiv/div.sv | 1535 +++++++++++++ wally-pipelined/src/muldiv/div.sv~ | 1921 +++++++++++++++++ wally-pipelined/src/muldiv/div/divide4x32.sv | 312 +-- wally-pipelined/src/muldiv/div/divide4x64.sv | 598 +---- wally-pipelined/src/muldiv/div/int32div.do | 4 +- wally-pipelined/src/muldiv/div/int64div.do | 4 +- wally-pipelined/src/muldiv/div/iter32.do | 2 +- wally-pipelined/src/muldiv/div/iter64.do | 2 +- .../src/muldiv/div/{muxs.sv => mux_div.sv} | 0 .../src/muldiv/div/shifters_div.sv | 106 + .../div/{shifters.sv => shifters_div.sv~} | 0 .../src/muldiv/div/test_int32div.sv | 8 +- wally-pipelined/src/muldiv/muldiv.sv | 97 +- .../src/wally/wallypipelinedhart.sv | 17 +- .../testbench/testbench-imperas.sv | 2 +- 22 files changed, 5918 insertions(+), 932 deletions(-) create mode 100644 wally-pipelined/config/rv64imc/BTBPredictor.txt create mode 100644 wally-pipelined/config/rv64imc/twoBitPredictor.txt create mode 100644 wally-pipelined/config/rv64imc/wally-config.vh create mode 100644 wally-pipelined/config/rv64imc/wally-constants.vh create mode 100755 wally-pipelined/src/muldiv/div.sv create mode 100755 wally-pipelined/src/muldiv/div.sv~ rename wally-pipelined/src/muldiv/div/{muxs.sv => mux_div.sv} (100%) create mode 100644 wally-pipelined/src/muldiv/div/shifters_div.sv rename wally-pipelined/src/muldiv/div/{shifters.sv => shifters_div.sv~} (100%) diff --git a/wally-pipelined/config/rv64imc/BTBPredictor.txt b/wally-pipelined/config/rv64imc/BTBPredictor.txt new file mode 100644 index 000000000..b761147c6 --- /dev/null +++ b/wally-pipelined/config/rv64imc/BTBPredictor.txt @@ -0,0 +1,1024 @@ +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000 diff --git a/wally-pipelined/config/rv64imc/twoBitPredictor.txt b/wally-pipelined/config/rv64imc/twoBitPredictor.txt new file mode 100644 index 000000000..ff57bd473 --- /dev/null +++ b/wally-pipelined/config/rv64imc/twoBitPredictor.txt @@ -0,0 +1,1024 @@ +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 diff --git a/wally-pipelined/config/rv64imc/wally-config.vh b/wally-pipelined/config/rv64imc/wally-config.vh new file mode 100644 index 000000000..a1150f78d --- /dev/null +++ b/wally-pipelined/config/rv64imc/wally-config.vh @@ -0,0 +1,100 @@ +////////////////////////////////////////// +// wally-config.vh +// +// Written: David_Harris@hmc.edu 4 January 2021 +// Modified: +// +// Purpose: Specify which features are configured +// Macros to determine which modes are supported based on MISA +// +// 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. +/////////////////////////////////////////// + +// RV32 or RV64: XLEN = 32 or 64 +`define XLEN 64 + +//`define MISA (32'h00000105) +`define MISA (32'h00001104 | 1<<5 | 1<<18 | 1 << 20 | 1 << 12 | 1 << 0) +`define A_SUPPORTED ((`MISA >> 0) % 2 == 1) +`define C_SUPPORTED ((`MISA >> 2) % 2 == 1) +`define D_SUPPORTED ((`MISA >> 3) % 2 == 1) +`define F_SUPPORTED ((`MISA >> 5) % 2 == 1) +`define M_SUPPORTED ((`MISA >> 12) % 2 == 1) +`define S_SUPPORTED ((`MISA >> 18) % 2 == 1) +`define U_SUPPORTED ((`MISA >> 20) % 2 == 1) +`define ZCSR_SUPPORTED 1 +`define COUNTERS 31 +`define ZCOUNTERS_SUPPORTED 1 +// N-mode user-level interrupts are depricated per Andrew Waterman 1/13/21 +//`define N_SUPPORTED ((MISA >> 13) % 2 == 1) +`define N_SUPPORTED 0 + +`define M_MODE (2'b11) +`define S_MODE (2'b01) +`define U_MODE (2'b00) + +// Microarchitectural Features +`define UARCH_PIPELINED 1 +`define UARCH_SUPERSCALR 0 +`define UARCH_SINGLECYCLE 0 +`define MEM_DCACHE 0 +`define MEM_DTIM 1 +`define MEM_ICACHE 0 +`define MEM_VIRTMEM 0 + +// Address space +`define RESET_VECTOR 64'h0000000080000000 + +// Bus Interface width +`define AHBW 64 + +// Peripheral Physiccal Addresses +// Peripheral memory space extends from BASE to BASE+RANGE +// Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits + +`define BOOTTIMBASE 32'h00000000 +`define BOOTTIMRANGE 32'h00003FFF +`define TIMBASE 32'h80000000 +`define TIMRANGE 32'h0007FFFF +`define CLINTBASE 32'h02000000 +`define CLINTRANGE 32'h0000FFFF +`define GPIOBASE 32'h10012000 +`define GPIORANGE 32'h000000FF +`define UARTBASE 32'h10000000 +`define UARTRANGE 32'h00000007 +`define PLICBASE 32'h0C000000 +`define PLICRANGE 32'h03FFFFFF + +// Test modes + +// Tie GPIO outputs back to inputs +`define GPIO_LOOPBACK_TEST 0 + +// Busybear special CSR config to match OVPSim +`define OVPSIM_CSR_CONFIG 0 + +// Hardware configuration +`define UART_PRESCALE 1 + +/* verilator lint_off STMTDLY */ +/* verilator lint_off WIDTH */ +/* verilator lint_off ASSIGNDLY */ +/* verilator lint_off PINCONNECTEMPTY */ + +`define TWO_BIT_PRELOAD "../config/rv64ic/twoBitPredictor.txt" +`define BTB_PRELOAD "../config/rv64ic/BTBPredictor.txt" +`define BPTYPE "BPGSHARE" // BPGLOBAL or BPTWOBIT or BPGSHARE diff --git a/wally-pipelined/config/rv64imc/wally-constants.vh b/wally-pipelined/config/rv64imc/wally-constants.vh new file mode 100644 index 000000000..55fb4e947 --- /dev/null +++ b/wally-pipelined/config/rv64imc/wally-constants.vh @@ -0,0 +1,31 @@ +////////////////////////////////////////// +// wally-constants.vh +// +// Written: tfleming@hmc.edu 4 March 2021 +// Modified: +// +// Purpose: Specify certain constants defined in the RISC-V 64-bit architecture. +// These macros should not be changed, except in the event of an +// update to the architecture or particularly special circumstances. +// +// 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. +/////////////////////////////////////////// + +// Virtual Memory Constants (sv39) +`define VPN_BITS 27 +`define PPN_BITS 44 +`define PA_BITS 56 diff --git a/wally-pipelined/src/ieu/forward.sv b/wally-pipelined/src/ieu/forward.sv index 3f38004eb..dd79fcc7a 100644 --- a/wally-pipelined/src/ieu/forward.sv +++ b/wally-pipelined/src/ieu/forward.sv @@ -27,12 +27,13 @@ module forward( // Detect hazards - input logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, RdE, RdM, RdW, - input logic MemReadE, MulDivE, CSRReadE, - input logic RegWriteM, RegWriteW, + input logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, RdE, RdM, RdW, + input logic MemReadE, MulDivE, CSRReadE, + input logic RegWriteM, RegWriteW, + input logic DivDoneW, // Forwarding controls output logic [1:0] ForwardAE, ForwardBE, - output logic LoadStallD, MulDivStallD, CSRRdStallD + output logic LoadStallD, MulDivStallD, CSRRdStallD ); always_comb begin @@ -48,8 +49,8 @@ module forward( end // Stall on dependent operations that finish in Mem Stage and can't bypass in time - assign LoadStallD = MemReadE & ((Rs1D == RdE) | (Rs2D == RdE)); - assign MulDivStallD = MulDivE & ((Rs1D == RdE) | (Rs2D == RdE)); // *** extend with stalls for divide - assign CSRRdStallD = CSRReadE & ((Rs1D == RdE) | (Rs2D == RdE)); + assign LoadStallD = MemReadE & ((Rs1D == RdE) | (Rs2D == RdE)); + assign MulDivStallD = MulDivE & ((Rs1D == RdE) | (Rs2D == RdE)) | MulDivE&~DivDoneW; // *** extend with stalls for divide + assign CSRRdStallD = CSRReadE & ((Rs1D == RdE) | (Rs2D == RdE)); endmodule diff --git a/wally-pipelined/src/ieu/ieu.sv b/wally-pipelined/src/ieu/ieu.sv index 85f029381..08d35fdfb 100644 --- a/wally-pipelined/src/ieu/ieu.sv +++ b/wally-pipelined/src/ieu/ieu.sv @@ -26,39 +26,40 @@ `include "wally-config.vh" module ieu ( - input logic clk, reset, + input logic clk, reset, // Decode Stage interface - input logic [31:0] InstrD, - input logic IllegalIEUInstrFaultD, - output logic IllegalBaseInstrFaultD, + input logic [31:0] InstrD, + input logic IllegalIEUInstrFaultD, + output logic IllegalBaseInstrFaultD, // Execute Stage interface - input logic [`XLEN-1:0] PCE, - input logic [`XLEN-1:0] PCLinkE, + input logic [`XLEN-1:0] PCE, + input logic [`XLEN-1:0] PCLinkE, output logic [`XLEN-1:0] PCTargetE, - output logic MulDivE, W64E, - output logic [2:0] Funct3E, + output logic MulDivE, W64E, + output logic [2:0] Funct3E, output logic [`XLEN-1:0] SrcAE, SrcBE, // Memory stage interface - input logic DataMisalignedM, - input logic DataAccessFaultM, - input logic SquashSCW, - output logic [1:0] MemRWM, - output logic [1:0] AtomicM, + input logic DataMisalignedM, + input logic DataAccessFaultM, + input logic SquashSCW, + output logic [1:0] MemRWM, + output logic [1:0] AtomicM, output logic [`XLEN-1:0] MemAdrM, WriteDataM, output logic [`XLEN-1:0] SrcAM, - output logic [2:0] Funct3M, + output logic [2:0] Funct3M, // Writeback stage - input logic [`XLEN-1:0] CSRReadValW, ReadDataW, MulDivResultW, + input logic [`XLEN-1:0] CSRReadValW, ReadDataW, MulDivResultW, // input logic [`XLEN-1:0] PCLinkW, - output logic InstrValidW, + output logic InstrValidW, // hazards - input logic StallE, StallM, StallW, - input logic FlushE, FlushM, FlushW, - output logic LoadStallD, MulDivStallD, CSRRdStallD, - output logic PCSrcE, + input logic StallE, StallM, StallW, + input logic FlushE, FlushM, FlushW, + output logic LoadStallD, MulDivStallD, CSRRdStallD, + output logic PCSrcE, + input logic DivDoneW, - output logic CSRReadM, CSRWriteM, PrivilegedM, - output logic CSRWritePendingDEM + output logic CSRReadM, CSRWriteM, PrivilegedM, + output logic CSRWritePendingDEM ); logic [2:0] ImmSrcD; @@ -78,5 +79,6 @@ module ieu ( controller c(.*); datapath dp(.*); forward fw(.*); + endmodule diff --git a/wally-pipelined/src/ifu/ifu.sv b/wally-pipelined/src/ifu/ifu.sv index 35844fca0..d1b4fbf57 100644 --- a/wally-pipelined/src/ifu/ifu.sv +++ b/wally-pipelined/src/ifu/ifu.sv @@ -80,7 +80,7 @@ module ifu ( logic ITLBFlushF = '0; // logic ITLBWriteF = '0; tlb #(3) itlb(clk, reset, SATP_REGW, PrivilegeModeW, PCF, PageTableEntryF, ITLBWriteF, ITLBFlushF, - ITLBInstrPAdrF, ITLBMissF, ITLBHitF); + ITLBInstrPAdrF, ITLBMissF, ITLBHitF); // branch predictor signals logic SelBPPredF; diff --git a/wally-pipelined/src/muldiv/div.sv b/wally-pipelined/src/muldiv/div.sv new file mode 100755 index 000000000..2d515ce1d --- /dev/null +++ b/wally-pipelined/src/muldiv/div.sv @@ -0,0 +1,1535 @@ +/////////////////////////////////////////// +// mul.sv +// +// Written: James.Stine@okstate.edu 1 February 2021 +// Modified: +// +// Purpose: Integer Divide instructions +// +// 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. +/////////////////////////////////////////// + +module div (Q, rem0, divdone, div0, N, D, clk, reset, start); + + input logic [63:0] N, D; + input logic clk; + input logic reset; + input logic start; + + output logic [63:0] Q; + output logic [63:0] rem0; + output logic div0; + output logic divdone; + + logic done; + logic enable; + logic state0; + logic V; + logic [7:0] Num; + logic [5:0] P, NumIter, RemShift; + logic [63:0] op1, op2, op1shift, Rem5; + logic [64:0] Qd, Rd, Qd2, Rd2; + logic [3:0] quotient; + logic otfzero; + logic shiftResult; + + // Divider goes the distance to 37 cycles + // (thanks the evil divisor for D = 0x1) + // but could theoretically be stopped when + // divdone is asserted. The enable signal + // turns off register storage thus invalidating + // any future cycles. + + // Shift D, if needed (for integer) + // needed to allow qst to be in range for integer + // division [1,2) and allow integer divide to work. + // + // The V or valid bit can be used to determine if D + // is 0 and thus a divide by 0 exception. This div0 + // exception is given to FSM to tell the operation to + // quit gracefully. + + // div0 produced output errors have untested results + // (it is assumed the OS would handle some output) + + lz64 p1 (P, V, D); + shifter_l64 p2 (op2, D, P); + assign op1 = N; + assign div0 = ~V; + + // #iter: N = m+v+s = m+(s+2) = m+2+s (mod k = 0) + // v = 2 since \rho < 1 (add 4 to make sure its a ceil) + adder #(8) cpa1 ({2'b0, P}, + {5'h0, shiftResult, ~shiftResult, 1'b0}, + Num); + + // Determine whether need to add just Q/Rem + assign shiftResult = P[0]; + // div by 2 (ceil) + assign NumIter = Num[6:1]; + assign RemShift = P; + + // FSM to control integer divider + // assume inputs are postive edge and + // datapath (divider) is negative edge + fsm64 fsm1 (enablev, state0v, donev, divdonev, otfzerov, + start, div0, NumIter, ~clk, reset); + + flopr #(1) rega (~clk, reset, donev, done); + flopr #(1) regb (~clk, reset, divdonev, divdone); + flopr #(1) regc (~clk, reset, otfzerov, otfzero); + flopr #(1) regd (~clk, reset, enablev, enable); + flopr #(1) rege (~clk, reset, state0v, state0); + + // To obtain a correct remainder the last bit of the + // quotient has to be aligned with a radix-r boundary. + // Since the quotient is in the range 1/2 < q < 2 (one + // integer bit and m fractional bits), this is achieved by + // shifting N right by v+s so that (m+v+s) mod k = 0. And, + // the quotient has to be aligned to the integer position. + + // Used a Brent-Kung for no reason (just wanted prefix -- might + // have gotten away with a RCA) + + // Actual divider unit FIXME: r16 (jes) + divide4x64 p3 (Qd, Rd, quotient, op1, op2, clk, reset, state0, + enable, otfzero, shiftResult); + + // Storage registers to hold contents stable + flopenr #(65) reg3 (clk, reset, enable, Rd, Rd2); + flopenr #(65) reg4 (clk, reset, enable, Qd, Qd2); + + // Probably not needed - just assigns results + assign Q = Qd2[63:0]; + assign Rem5 = Rd2[64:1]; + + // Adjust remainder by m (no need to adjust by + // n ln(r) + shifter_r64 p4 (rem0, Rem5, RemShift); + +endmodule // int32div + +module divide4x64 (Q, rem0, quotient, op1, op2, clk, reset, state0, + enable, otfzero, shiftResult); + + input logic [63:0] op1, op2; + input logic clk, state0; + input logic reset; + input logic enable; + input logic otfzero; + input logic shiftResult; + + output logic [64:0] rem0; + output logic [64:0] Q; + output logic [3:0] quotient; + + logic [67:0] Sum, Carry; + logic [64:0] Qstar; + logic [64:0] QMstar; + logic [7:0] qtotal; + logic [67:0] SumN, CarryN, SumN2, CarryN2; + logic [67:0] divi1, divi2, divi1c, divi2c, dive1; + logic [67:0] mdivi_temp, mdivi; + logic zero; + logic [1:0] qsel; + logic [1:0] Qin, QMin; + logic CshiftQ, CshiftQM; + logic [67:0] rem1, rem2, rem3; + logic [67:0] SumR, CarryR; + logic [64:0] Qt; + + // Create one's complement values of Divisor (for q*D) + assign divi1 = {3'h0, op2, 1'b0}; + assign divi2 = {2'h0, op2, 2'b0}; + assign divi1c = ~divi1; + assign divi2c = ~divi2; + // Shift x1 if not mod k + mux2 #(68) mx1 ({3'b000, op1, 1'b0}, {4'h0, op1}, shiftResult, dive1); + + // I I I . F F F F F ... (Robertson Criteria - \rho * qmax * D) + mux2 #(68) mx2 ({CarryN2[65:0], 2'h0}, 68'h0, state0, CarryN); + mux2 #(68) mx3 ({SumN2[65:0], 2'h0}, dive1, state0, SumN); + // Simplify QST + adder #(8) cpa1 (SumN[67:60], CarryN[67:60], qtotal); + // q = {+2, +1, -1, -2} else q = 0 + qst4 pd1 (qtotal[7:1], divi1[63:61], quotient); + assign ulp = quotient[2]|quotient[3]; + assign zero = ~(quotient[3]|quotient[2]|quotient[1]|quotient[0]); + // Map to binary encoding + assign qsel[1] = quotient[3]|quotient[2]; + assign qsel[0] = quotient[3]|quotient[1]; + mux4 #(68) mx4 (divi2, divi1, divi1c, divi2c, qsel, mdivi_temp); + mux2 #(68) mx5 (mdivi_temp, 68'h0, zero, mdivi); + csa #(68) csa1 (mdivi, SumN, {CarryN[67:1], ulp}, Sum, Carry); + // regs : save CSA + flopenr #(68) reg1 (clk, reset, enable, Sum, SumN2); + flopenr #(68) reg2 (clk, reset, enable, Carry, CarryN2); + // OTF + ls_control otf1 (quotient, Qin, QMin, CshiftQ, CshiftQM); + otf #(65) otf2 (Qin, QMin, CshiftQ, CshiftQM, clk, + otfzero, enable, Qstar, QMstar); + + // Correction and generation of Remainder + adder #(68) cpa2 (SumN2[67:0], CarryN2[67:0], rem1); + // Add back +D as correction + csa #(68) csa2 (CarryN2[67:0], SumN2[67:0], divi1, SumR, CarryR); + adder #(68) cpa3 (SumR, CarryR, rem2); + // Choose remainder (Rem or Rem+D) + mux2 #(68) mx6 (rem1, rem2, rem1[67], rem3); + // Choose correct Q or QM + mux2 #(65) mx7 (Qstar, QMstar, rem1[67], Qt); + // Final results + assign rem0 = rem3[64:0]; + assign Q = Qt; + +endmodule // divide4x64 + +module ls_control (quot, Qin, QMin, CshiftQ, CshiftQM); + + input logic [3:0] quot; + + output logic [1:0] Qin; + output logic [1:0] QMin; + output logic CshiftQ; + output logic CshiftQM; + + // Load/Store Control for OTF + assign Qin[1] = (quot[1]) | (quot[3]) | (quot[0]); + assign Qin[0] = (quot[1]) | (quot[2]); + assign QMin[1] = (quot[1]) | (!quot[3]&!quot[2]&!quot[1]&!quot[0]); + assign QMin[0] = (quot[3]) | (quot[0]) | + (!quot[3]&!quot[2]&!quot[1]&!quot[0]); + assign CshiftQ = (quot[1]) | (quot[0]); + assign CshiftQM = (quot[3]) | (quot[2]); + +endmodule + +// On-the-fly Conversion per Ercegovac/Lang + +module otf #(parameter WIDTH=8) + (Qin, QMin, CshiftQ, CshiftQM, clk, reset, enable, R2Q, R1Q); + + input logic [1:0] Qin, QMin; + input logic CshiftQ, CshiftQM; + input logic clk; + input logic reset; + input logic enable; + + output logic [WIDTH-1:0] R2Q; + output logic [WIDTH-1:0] R1Q; + + logic [WIDTH-1:0] Qstar, QMstar; + logic [WIDTH-1:0] M1Q, M2Q; + + // QM + mux2 #(WIDTH) m1 (QMstar, Qstar, CshiftQM, M1Q); + flopenr #(WIDTH) r1 (clk, reset, enable, {M1Q[WIDTH-3:0], QMin}, R1Q); + // Q + mux2 #(WIDTH) m2 (Qstar, QMstar, CshiftQ, M2Q); + flopenr #(WIDTH) r2 (clk, reset, enable, {M2Q[WIDTH-3:0], Qin}, R2Q); + + assign Qstar = R2Q; + assign QMstar = R1Q; + +endmodule // otf8 + +module adder #(parameter WIDTH=8) (input logic [WIDTH-1:0] a, b, + output logic [WIDTH-1:0] y); + + assign y = a + b; + +endmodule // adder + +module fa (input logic a, b, c, output logic sum, carry); + + assign sum = a^b^c; + assign carry = a&b|a&c|b&c; + +endmodule // fa + +module csa #(parameter WIDTH=8) (input logic [WIDTH-1:0] a, b, c, + output logic [WIDTH-1:0] sum, carry); + + logic [WIDTH:0] carry_temp; + genvar i; + generate + for (i=0;i B. LT and GT are both '0' if A = B. + +module magcompare2b (LT, GT, A, B); + + input logic [1:0] A; + input logic [1:0] B; + + output logic LT; + output logic GT; + + // Determine if A < B using a minimized sum-of-products expression + assign LT = ~A[1]&B[1] | ~A[1]&~A[0]&B[0] | ~A[0]&B[1]&B[0]; + // Determine if A > B using a minimized sum-of-products expression + assign GT = A[1]&~B[1] | A[1]&A[0]&~B[0] | A[0]&~B[1]&~B[0]; + +endmodule // magcompare2b + +// J. E. Stine and M. J. Schulte, "A combined two's complement and +// floating-point comparator," 2005 IEEE International Symposium on +// Circuits and Systems, Kobe, 2005, pp. 89-92 Vol. 1. +// doi: 10.1109/ISCAS.2005.1464531 + +module magcompare8 (LT, EQ, A, B); + + input logic [7:0] A; + input logic [7:0] B; + + logic [3:0] s; + logic [3:0] t; + logic [1:0] u; + logic [1:0] v; + logic GT; + //wire LT; + + output logic EQ; + output logic LT; + + magcompare2b mag1 (s[0], t[0], A[1:0], B[1:0]); + magcompare2b mag2 (s[1], t[1], A[3:2], B[3:2]); + magcompare2b mag3 (s[2], t[2], A[5:4], B[5:4]); + magcompare2b mag4 (s[3], t[3], A[7:6], B[7:6]); + + magcompare2b mag5 (u[0], v[0], t[1:0], s[1:0]); + magcompare2b mag6 (u[1], v[1], t[3:2], s[3:2]); + + magcompare2b mag7 (LT, GT, v[1:0], u[1:0]); + + assign EQ = ~(GT | LT); + +endmodule // magcompare8 + +module shifter_l64 (Z, A, Shift); + + input logic [63:0] A; + input logic [5:0] Shift; + + logic [63:0] stage1; + logic [63:0] stage2; + logic [63:0] stage3; + logic [63:0] stage4; + logic [63:0] stage5; + logic [31:0] thirtytwozeros = 32'h0; + logic [15:0] sixteenzeros = 16'h0; + logic [ 7:0] eightzeros = 8'h0; + logic [ 3:0] fourzeros = 4'h0; + logic [ 1:0] twozeros = 2'b00; + logic onezero = 1'b0; + + output logic [63:0] Z; + + mux2 #(64) mx01(A, {A[31:0], thirtytwozeros}, Shift[5], stage1); + mux2 #(64) mx02(stage1, {stage1[47:0], sixteenzeros}, Shift[4], stage2); + mux2 #(64) mx03(stage2, {stage2[55:0], eightzeros}, Shift[3], stage3); + mux2 #(64) mx04(stage3, {stage3[59:0], fourzeros}, Shift[2], stage4); + mux2 #(64) mx05(stage4, {stage4[61:0], twozeros}, Shift[1], stage5); + mux2 #(64) mx06(stage5, {stage5[62:0], onezero}, Shift[0], Z); + +endmodule // shifter_l64 + +module shifter_r64 (Z, A, Shift); + + input logic [63:0] A; + input logic [5:0] Shift; + + logic [63:0] stage1; + logic [63:0] stage2; + logic [63:0] stage3; + logic [63:0] stage4; + logic [63:0] stage5; + logic [31:0] thirtytwozeros = 32'h0; + logic [15:0] sixteenzeros = 16'h0; + logic [ 7:0] eightzeros = 8'h0; + logic [ 3:0] fourzeros = 4'h0; + logic [ 1:0] twozeros = 2'b00; + logic onezero = 1'b0; + + output logic [63:0] Z; + + mux2 #(64) mx01(A, {thirtytwozeros, A[63:32]}, Shift[5], stage1); + mux2 #(64) mx02(stage1, {sixteenzeros, stage1[63:16]}, Shift[4], stage2); + mux2 #(64) mx03(stage2, {eightzeros, stage2[63:8]}, Shift[3], stage3); + mux2 #(64) mx04(stage3, {fourzeros, stage3[63:4]}, Shift[2], stage4); + mux2 #(64) mx05(stage4, {twozeros, stage4[63:2]}, Shift[1], stage5); + mux2 #(64) mx06(stage5, {onezero, stage5[63:1]}, Shift[0], Z); + +endmodule // shifter_r64 + +module shifter_l32 (Z, A, Shift); + + input logic [31:0] A; + input logic [4:0] Shift; + + logic [31:0] stage1; + logic [31:0] stage2; + logic [31:0] stage3; + logic [31:0] stage4; + logic [15:0] sixteenzeros = 16'h0; + logic [ 7:0] eightzeros = 8'h0; + logic [ 3:0] fourzeros = 4'h0; + logic [ 1:0] twozeros = 2'b00; + logic onezero = 1'b0; + + output logic [31:0] Z; + + mux2 #(32) mx01(A, {A[15:0], sixteenzeros}, Shift[4], stage1); + mux2 #(32) mx02(stage1, {stage1[23:0], eightzeros}, Shift[3], stage2); + mux2 #(32) mx03(stage2, {stage2[27:0], fourzeros}, Shift[2], stage3); + mux2 #(32) mx04(stage3, {stage3[29:0], twozeros}, Shift[1], stage4); + mux2 #(32) mx05(stage4, {stage4[30:0], onezero}, Shift[0], Z); + +endmodule // shifter_l32 + +module shifter_r32 (Z, A, Shift); + + input logic [31:0] A; + input logic [4:0] Shift; + + logic [31:0] stage1; + logic [31:0] stage2; + logic [31:0] stage3; + logic [31:0] stage4; + logic [15:0] sixteenzeros = 16'h0; + logic [ 7:0] eightzeros = 8'h0; + logic [ 3:0] fourzeros = 4'h0; + logic [ 1:0] twozeros = 2'b00; + logic onezero = 1'b0; + + output logic [31:0] Z; + + mux2 #(32) mx01(A, {sixteenzeros, A[31:16]}, Shift[4], stage1); + mux2 #(32) mx02(stage1, {eightzeros, stage1[31:8]}, Shift[3], stage2); + mux2 #(32) mx03(stage2, {fourzeros, stage2[31:4]}, Shift[2], stage3); + mux2 #(32) mx04(stage3, {twozeros, stage3[31:2]}, Shift[1], stage4); + mux2 #(32) mx05(stage4, {onezero, stage4[31:1]}, Shift[0], Z); + +endmodule // shifter_r32 + diff --git a/wally-pipelined/src/muldiv/div.sv~ b/wally-pipelined/src/muldiv/div.sv~ new file mode 100755 index 000000000..0cb6b0554 --- /dev/null +++ b/wally-pipelined/src/muldiv/div.sv~ @@ -0,0 +1,1921 @@ +module int64div (Q, done, divdone, rem0, div0, N, D, clk, reset, start); + + input logic [63:0] N, D; + input logic clk; + input logic reset; + input logic start; + + output logic [63:0] Q; + output logic [63:0] rem0; + output logic div0; + output logic done; + output logic divdone; + + logic enable; + logic state0; + logic V; + logic [7:0] Num; + logic [5:0] P, NumIter, RemShift; + logic [63:0] op1, op2, op1shift, Rem5; + logic [64:0] Qd, Rd, Qd2, Rd2; + logic [3:0] quotient; + logic otfzero; + logic shiftResult; + + // Divider goes the distance to 37 cycles + // (thanks the evil divisor for D = 0x1) + // but could theoretically be stopped when + // divdone is asserted. The enable signal + // turns off register storage thus invalidating + // any future cycles. + + // Shift D, if needed (for integer) + // needed to allow qst to be in range for integer + // division [1,2) and allow integer divide to work. + // + // The V or valid bit can be used to determine if D + // is 0 and thus a divide by 0 exception. This div0 + // exception is given to FSM to tell the operation to + // quit gracefully. + + // div0 produced output errors have untested results + // (it is assumed the OS would handle some output) + + lz64 p1 (P, V, D); + shifter_l64 p2 (op2, D, P); + assign op1 = N; + assign div0 = ~V; + + // Brent-Kung adder chosen for the heck of it and + // since so small (maybe could have used a RCA) + + // #iter: N = m+v+s = m+(s+2) = m+2+s (mod k = 0) + // v = 2 since \rho < 1 (add 4 to make sure its a ceil) + bk8 cpa1 (co1, Num, {2'b0, P}, + {5'h0, shiftResult, ~shiftResult, 1'b0}, 1'b0); + + // Determine whether need to add just Q/Rem + assign shiftResult = P[0]; + // div by 2 (ceil) + assign NumIter = Num[6:1]; + assign RemShift = P; + + // FSM to control integer divider + // assume inputs are postive edge and + // datapath (divider) is negative edge + fsm64 fsm1 (enablev, state0v, donev, divdonev, otfzerov, + start, div0, NumIter, ~clk, reset); + + flopr #(1) rega (~clk, reset, donev, done); + flopr #(1) regb (~clk, reset, divdonev, divdone); + flopr #(1) regc (~clk, reset, otfzerov, otfzero); + flopr #(1) regd (~clk, reset, enablev, enable); + flopr #(1) rege (~clk, reset, state0v, state0); + + // To obtain a correct remainder the last bit of the + // quotient has to be aligned with a radix-r boundary. + // Since the quotient is in the range 1/2 < q < 2 (one + // integer bit and m fractional bits), this is achieved by + // shifting N right by v+s so that (m+v+s) mod k = 0. And, + // the quotient has to be aligned to the integer position. + + // Used a Brent-Kung for no reason (just wanted prefix -- might + // have gotten away with a RCA) + + // Actual divider unit FIXME: r16 (jes) + divide4x64 p3 (Qd, Rd, quotient, op1, op2, clk, reset, state0, + enable, otfzero, shiftResult); + + // Storage registers to hold contents stable + flopenr #(65) reg3 (clk, reset, enable, Rd, Rd2); + flopenr #(65) reg4 (clk, reset, enable, Qd, Qd2); + + // Probably not needed - just assigns results + assign Q = Qd2[63:0]; + assign Rem5 = Rd2[64:1]; + + // Adjust remainder by m (no need to adjust by + // n ln(r) + shifter_r64 p4 (rem0, Rem5, RemShift); + +endmodule // int32div + +module divide4x64 (Q, rem0, quotient, op1, op2, clk, reset, state0, + enable, otfzero, shiftResult); + + input logic [63:0] op1, op2; + input logic clk, state0; + input logic reset; + input logic enable; + input logic otfzero; + input logic shiftResult; + + output logic [64:0] rem0; + output logic [64:0] Q; + output logic [3:0] quotient; + + logic [67:0] Sum, Carry; + logic [64:0] Qstar; + logic [64:0] QMstar; + logic [7:0] qtotal; + logic [67:0] SumN, CarryN, SumN2, CarryN2; + logic [67:0] divi1, divi2, divi1c, divi2c, dive1; + logic [67:0] mdivi_temp, mdivi; + logic zero; + logic [1:0] qsel; + logic [1:0] Qin, QMin; + logic CshiftQ, CshiftQM; + logic [67:0] rem1, rem2, rem3; + logic [67:0] SumR, CarryR; + logic [64:0] Qt; + + // Create one's complement values of Divisor (for q*D) + assign divi1 = {3'h0, op2, 1'b0}; + assign divi2 = {2'h0, op2, 2'b0}; + assign divi1c = ~divi1; + assign divi2c = ~divi2; + // Shift x1 if not mod k + mux2 #(68) mx1 ({3'b000, op1, 1'b0}, {4'h0, op1}, shiftResult, dive1); + + // I I I . F F F F F ... (Robertson Criteria - \rho * qmax * D) + mux2 #(68) mx2 ({CarryN2[65:0], 2'h0}, 68'h0, state0, CarryN); + mux2 #(68) mx3 ({SumN2[65:0], 2'h0}, dive1, state0, SumN); + // Simplify QST + adder #(8) cpa1 (SumN[67:60], CarryN[67:60], qtotal); + // q = {+2, +1, -1, -2} else q = 0 + qst4 pd1 (qtotal[7:1], divi1[63:61], quotient); + assign ulp = quotient[2]|quotient[3]; + assign zero = ~(quotient[3]|quotient[2]|quotient[1]|quotient[0]); + // Map to binary encoding + assign qsel[1] = quotient[3]|quotient[2]; + assign qsel[0] = quotient[3]|quotient[1]; + mux4 #(68) mx4 (divi2, divi1, divi1c, divi2c, qsel, mdivi_temp); + mux2 #(68) mx5 (mdivi_temp, 68'h0, zero, mdivi); + csa #(68) csa1 (mdivi, SumN, {CarryN[67:1], ulp}, Sum, Carry); + // regs : save CSA + flopenr #(68) reg1 (clk, reset, enable, Sum, SumN2); + flopenr #(68) reg2 (clk, reset, enable, Carry, CarryN2); + // OTF + ls_control otf1 (quotient, Qin, QMin, CshiftQ, CshiftQM); + otf #(65) otf2 (Qin, QMin, CshiftQ, CshiftQM, clk, + otfzero, enable, Qstar, QMstar); + + // Correction and generation of Remainder + add68 cpa2 (cout1, rem1, SumN2[67:0], CarryN2[67:0], 1'b0); + // Add back +D as correction + csa #(68) csa2 (CarryN2[67:0], SumN2[67:0], divi1, SumR, CarryR); + add68 cpa3 (cout2, rem2, SumR, CarryR, 1'b0); + // Choose remainder (Rem or Rem+D) + mux2 #(68) mx6 (rem1, rem2, rem1[67], rem3); + // Choose correct Q or QM + mux2 #(65) mx7 (Qstar, QMstar, rem1[67], Qt); + // Final results + assign rem0 = rem3[64:0]; + assign Q = Qt; + +endmodule // divide4x64 + +module ls_control (quot, Qin, QMin, CshiftQ, CshiftQM); + + input logic [3:0] quot; + + output logic [1:0] Qin; + output logic [1:0] QMin; + output logic CshiftQ; + output logic CshiftQM; + + assign Qin[1] = (quot[1]) | (quot[3]) | (quot[0]); + assign Qin[0] = (quot[1]) | (quot[2]); + assign QMin[1] = (quot[1]) | (!quot[3]&!quot[2]&!quot[1]&!quot[0]); + assign QMin[0] = (quot[3]) | (quot[0]) | + (!quot[3]&!quot[2]&!quot[1]&!quot[0]); + assign CshiftQ = (quot[1]) | (quot[0]); + assign CshiftQM = (quot[3]) | (quot[2]); + + endmodule + +module otf #(parameter WIDTH=8) + (Qin, QMin, CshiftQ, CshiftQM, clk, reset, enable, R2Q, R1Q); + + input logic [1:0] Qin, QMin; + input logic CshiftQ, CshiftQM; + input logic clk; + input logic reset; + input logic enable; + + output logic [WIDTH-1:0] R2Q; + output logic [WIDTH-1:0] R1Q; + + logic [WIDTH-1:0] Qstar, QMstar; + logic [WIDTH-1:0] M1Q, M2Q; + + // QM + mux2 #(WIDTH) m1 (QMstar, Qstar, CshiftQM, M1Q); + flopenr #(WIDTH) r1 (clk, reset, enable, {M1Q[WIDTH-3:0], QMin}, R1Q); + // Q + mux2 #(WIDTH) m2 (Qstar, QMstar, CshiftQ, M2Q); + flopenr #(WIDTH) r2 (clk, reset, enable, {M2Q[WIDTH-3:0], Qin}, R2Q); + + assign Qstar = R2Q; + assign QMstar = R1Q; + + endmodule // otf8 + + module adder #(parameter WIDTH=8) (input logic [WIDTH-1:0] a, b, + output logic [WIDTH-1:0] y); + + assign y = a + b; + + endmodule // adder + + module fa (input logic a, b, c, output logic sum, carry); + + assign sum = a^b^c; + assign carry = a&b|a&c|b&c; + + endmodule // fa + + module csa #(parameter WIDTH=8) (input logic [WIDTH-1:0] a, b, c, + output logic [WIDTH-1:0] sum, carry); + + logic [WIDTH:0] carry_temp; + genvar i; + generate + for (i=0;i B. LT and GT are both '0' if A = B. + +module magcompare2b (LT, GT, A, B); + + input logic [1:0] A; + input logic [1:0] B; + + output logic LT; + output logic GT; + + // Determine if A < B using a minimized sum-of-products expression + assign LT = ~A[1]&B[1] | ~A[1]&~A[0]&B[0] | ~A[0]&B[1]&B[0]; + // Determine if A > B using a minimized sum-of-products expression + assign GT = A[1]&~B[1] | A[1]&A[0]&~B[0] | A[0]&~B[1]&~B[0]; + +endmodule // magcompare2b + +// J. E. Stine and M. J. Schulte, "A combined two's complement and +// floating-point comparator," 2005 IEEE International Symposium on +// Circuits and Systems, Kobe, 2005, pp. 89-92 Vol. 1. +// doi: 10.1109/ISCAS.2005.1464531 + +module magcompare8 (LT, EQ, A, B); + + input logic [7:0] A; + input logic [7:0] B; + + logic [3:0] s; + logic [3:0] t; + logic [1:0] u; + logic [1:0] v; + logic GT; + //wire LT; + + output logic EQ; + output logic LT; + + magcompare2b mag1 (s[0], t[0], A[1:0], B[1:0]); + magcompare2b mag2 (s[1], t[1], A[3:2], B[3:2]); + magcompare2b mag3 (s[2], t[2], A[5:4], B[5:4]); + magcompare2b mag4 (s[3], t[3], A[7:6], B[7:6]); + + magcompare2b mag5 (u[0], v[0], t[1:0], s[1:0]); + magcompare2b mag6 (u[1], v[1], t[3:2], s[3:2]); + + magcompare2b mag7 (LT, GT, v[1:0], u[1:0]); + + assign EQ = ~(GT | LT); + +endmodule // magcompare8 diff --git a/wally-pipelined/src/muldiv/div/divide4x32.sv b/wally-pipelined/src/muldiv/div/divide4x32.sv index 9b0ac2b4c..c5c311701 100755 --- a/wally-pipelined/src/muldiv/div/divide4x32.sv +++ b/wally-pipelined/src/muldiv/div/divide4x32.sv @@ -50,8 +50,9 @@ module int32div (Q, done, divdone, rem0, div0, N, D, clk, reset, start); // #iter: N = m+v+s = m+(s+2) = m+2+s (mod k = 0) // v = 2 since \rho < 1 (add 4 to make sure its a ceil) - bk6 cpa1 (co1, Num, {1'b0, P}, - {3'h0, shiftResult, ~shiftResult,1'b0}, 1'b0); + adder #(6) cpa1 ({1'b0, P}, + {3'h0, shiftResult, ~shiftResult,1'b0}, + Num); // Determine whether need to add just Q/Rem assign shiftResult = P[0]; @@ -160,10 +161,10 @@ module divide4x32 (Q, rem0, quotient, op1, op2, clk, reset, state0, otfzero, enable, Qstar, QMstar); // Correction and generation of Remainder - add36 cpa2 (cout1, rem1, SumN2[35:0], CarryN2[35:0], 1'b0); + adder #(36) cpa2 (SumN2[35:0], CarryN2[35:0], rem1); // Add back +D as correction csa #(36) csa2 (CarryN2[35:0], SumN2[35:0], divi1, SumR, CarryR); - add36 cpa3 (cout2, rem2, SumR, CarryR, 1'b0); + adder #(36) cpa3 (SumR, CarryR, rem2); // Choose remainder (Rem or Rem+D) mux2 #(36) mx6 (rem1, rem2, rem1[35], rem3); // Choose correct Q or QM @@ -349,306 +350,7 @@ module floprc #(parameter WIDTH = 8) endmodule // qst4 -// Ladner-Fischer Prefix Adder - -module add36 (cout, sum, a, b, cin); - - input logic [35:0] a, b; - input logic cin; - output logic [35:0] sum; - output logic cout; - - logic [36:0] p,g; - logic [35:0] c; - - // pre-computation - assign p={a^b,1'b0}; - assign g={a&b, cin}; - - // prefix tree - ladner_fischer36 prefix_tree(c, p[35:0], g[35:0]); - - // post-computation - assign sum=p[36:1]^c; - assign cout=g[36]|(p[36]&c[35]); - -endmodule // add36 - -module ladner_fischer36 (c, p, g); - - input logic [35:0] p; - input logic [35:0] g; - - output logic [36:1] c; - - // parallel-prefix, Ladner-Fischer - - // Stage 1: Generates G/P pairs that span 1 bits - grey b_1_0 (G_1_0, {g[1],g[0]}, p[1]); - black b_3_2 (G_3_2, P_3_2, {g[3],g[2]}, {p[3],p[2]}); - black b_5_4 (G_5_4, P_5_4, {g[5],g[4]}, {p[5],p[4]}); - black b_7_6 (G_7_6, P_7_6, {g[7],g[6]}, {p[7],p[6]}); - black b_9_8 (G_9_8, P_9_8, {g[9],g[8]}, {p[9],p[8]}); - black b_11_10 (G_11_10, P_11_10, {g[11],g[10]}, {p[11],p[10]}); - black b_13_12 (G_13_12, P_13_12, {g[13],g[12]}, {p[13],p[12]}); - black b_15_14 (G_15_14, P_15_14, {g[15],g[14]}, {p[15],p[14]}); - - black b_17_16 (G_17_16, P_17_16, {g[17],g[16]}, {p[17],p[16]}); - black b_19_18 (G_19_18, P_19_18, {g[19],g[18]}, {p[19],p[18]}); - black b_21_20 (G_21_20, P_21_20, {g[21],g[20]}, {p[21],p[20]}); - black b_23_22 (G_23_22, P_23_22, {g[23],g[22]}, {p[23],p[22]}); - black b_25_24 (G_25_24, P_25_24, {g[25],g[24]}, {p[25],p[24]}); - black b_27_26 (G_27_26, P_27_26, {g[27],g[26]}, {p[27],p[26]}); - black b_29_28 (G_29_28, P_29_28, {g[29],g[28]}, {p[29],p[28]}); - black b_31_30 (G_31_30, P_31_30, {g[31],g[30]}, {p[31],p[30]}); - - black b_33_32 (G_33_32, P_33_32, {g[33],g[32]}, {p[33],p[32]}); - black b_35_34 (G_35_34, P_35_34, {g[35],g[34]}, {p[35],p[34]}); - - // Stage 2: Generates G/P pairs that span 2 bits - grey g_3_0 (G_3_0, {G_3_2,G_1_0}, P_3_2); - black b_7_4 (G_7_4, P_7_4, {G_7_6,G_5_4}, {P_7_6,P_5_4}); - black b_11_8 (G_11_8, P_11_8, {G_11_10,G_9_8}, {P_11_10,P_9_8}); - black b_15_12 (G_15_12, P_15_12, {G_15_14,G_13_12}, {P_15_14,P_13_12}); - black b_19_16 (G_19_16, P_19_16, {G_19_18,G_17_16}, {P_19_18,P_17_16}); - black b_23_20 (G_23_20, P_23_20, {G_23_22,G_21_20}, {P_23_22,P_21_20}); - black b_27_24 (G_27_24, P_27_24, {G_27_26,G_25_24}, {P_27_26,P_25_24}); - black b_31_28 (G_31_28, P_31_28, {G_31_30,G_29_28}, {P_31_30,P_29_28}); - - black b_35_32 (G_35_32, P_35_32, {G_35_34,G_33_32}, {P_35_34,P_33_32}); - - // Stage 3: Generates G/P pairs that span 4 bits - grey g_5_0 (G_5_0, {G_5_4,G_3_0}, P_5_4); - grey g_7_0 (G_7_0, {G_7_4,G_3_0}, P_7_4); - black b_13_8 (G_13_8, P_13_8, {G_13_12,G_11_8}, {P_13_12,P_11_8}); - black b_15_8 (G_15_8, P_15_8, {G_15_12,G_11_8}, {P_15_12,P_11_8}); - black b_21_16 (G_21_16, P_21_16, {G_21_20,G_19_16}, {P_21_20,P_19_16}); - black b_23_16 (G_23_16, P_23_16, {G_23_20,G_19_16}, {P_23_20,P_19_16}); - black b_29_24 (G_29_24, P_29_24, {G_29_28,G_27_24}, {P_29_28,P_27_24}); - black b_31_24 (G_31_24, P_31_24, {G_31_28,G_27_24}, {P_31_28,P_27_24}); - - black b_37_32 (G_37_32, P_37_32, {G_37_36,G_35_32}, {P_37_36,P_35_32}); - black b_39_32 (G_39_32, P_39_32, {G_39_36,G_35_32}, {P_39_36,P_35_32}); - - // Stage 4: Generates G/P pairs that span 8 bits - grey g_9_0 (G_9_0, {G_9_8,G_7_0}, P_9_8); - grey g_11_0 (G_11_0, {G_11_8,G_7_0}, P_11_8); - grey g_13_0 (G_13_0, {G_13_8,G_7_0}, P_13_8); - grey g_15_0 (G_15_0, {G_15_8,G_7_0}, P_15_8); - black b_25_16 (G_25_16, P_25_16, {G_25_24,G_23_16}, {P_25_24,P_23_16}); - black b_27_16 (G_27_16, P_27_16, {G_27_24,G_23_16}, {P_27_24,P_23_16}); - black b_29_16 (G_29_16, P_29_16, {G_29_24,G_23_16}, {P_29_24,P_23_16}); - black b_31_16 (G_31_16, P_31_16, {G_31_24,G_23_16}, {P_31_24,P_23_16}); - - black b_41_32 (G_41_32, P_41_32, {G_41_40,G_39_32}, {P_41_40,P_39_32}); - black b_43_32 (G_43_32, P_43_32, {G_43_40,G_39_32}, {P_43_40,P_39_32}); - black b_45_32 (G_45_32, P_45_32, {G_45_40,G_39_32}, {P_45_40,P_39_32}); - black b_47_32 (G_47_32, P_47_32, {G_47_40,G_39_32}, {P_47_40,P_39_32}); - - // Stage 5: Generates G/P pairs that span 16 bits - grey g_17_0 (G_17_0, {G_17_16,G_15_0}, P_17_16); - grey g_19_0 (G_19_0, {G_19_16,G_15_0}, P_19_16); - grey g_21_0 (G_21_0, {G_21_16,G_15_0}, P_21_16); - grey g_23_0 (G_23_0, {G_23_16,G_15_0}, P_23_16); - grey g_25_0 (G_25_0, {G_25_16,G_15_0}, P_25_16); - grey g_27_0 (G_27_0, {G_27_16,G_15_0}, P_27_16); - grey g_29_0 (G_29_0, {G_29_16,G_15_0}, P_29_16); - grey g_31_0 (G_31_0, {G_31_16,G_15_0}, P_31_16); - - black b_49_32 (G_49_32, P_49_32, {G_49_48,G_47_32}, {P_49_48,P_47_32}); - black b_51_32 (G_51_32, P_51_32, {G_51_48,G_47_32}, {P_51_48,P_47_32}); - black b_53_32 (G_53_32, P_53_32, {G_53_48,G_47_32}, {P_53_48,P_47_32}); - black b_55_32 (G_55_32, P_55_32, {G_55_48,G_47_32}, {P_55_48,P_47_32}); - black b_57_32 (G_57_32, P_57_32, {G_57_48,G_47_32}, {P_57_48,P_47_32}); - black b_59_32 (G_59_32, P_59_32, {G_59_48,G_47_32}, {P_59_48,P_47_32}); - black b_61_32 (G_61_32, P_61_32, {G_61_48,G_47_32}, {P_61_48,P_47_32}); - black b_63_32 (G_63_32, P_63_32, {G_63_48,G_47_32}, {P_63_48,P_47_32}); - - // Stage 6: Generates G/P pairs that span 32 bits - grey g_33_0 (G_33_0, {G_33_32,G_31_0}, P_33_32); - grey g_35_0 (G_35_0, {G_35_32,G_31_0}, P_35_32); - grey g_37_0 (G_37_0, {G_37_32,G_31_0}, P_37_32); - grey g_39_0 (G_39_0, {G_39_32,G_31_0}, P_39_32); - grey g_41_0 (G_41_0, {G_41_32,G_31_0}, P_41_32); - grey g_43_0 (G_43_0, {G_43_32,G_31_0}, P_43_32); - grey g_45_0 (G_45_0, {G_45_32,G_31_0}, P_45_32); - grey g_47_0 (G_47_0, {G_47_32,G_31_0}, P_47_32); - - grey g_49_0 (G_49_0, {G_49_32,G_31_0}, P_49_32); - grey g_51_0 (G_51_0, {G_51_32,G_31_0}, P_51_32); - grey g_53_0 (G_53_0, {G_53_32,G_31_0}, P_53_32); - grey g_55_0 (G_55_0, {G_55_32,G_31_0}, P_55_32); - grey g_57_0 (G_57_0, {G_57_32,G_31_0}, P_57_32); - grey g_59_0 (G_59_0, {G_59_32,G_31_0}, P_59_32); - grey g_61_0 (G_61_0, {G_61_32,G_31_0}, P_61_32); - grey g_63_0 (G_63_0, {G_63_32,G_31_0}, P_63_32); - - // Extra grey cell stage - grey g_2_0 (G_2_0, {g[2],G_1_0}, p[2]); - grey g_4_0 (G_4_0, {g[4],G_3_0}, p[4]); - grey g_6_0 (G_6_0, {g[6],G_5_0}, p[6]); - grey g_8_0 (G_8_0, {g[8],G_7_0}, p[8]); - grey g_10_0 (G_10_0, {g[10],G_9_0}, p[10]); - grey g_12_0 (G_12_0, {g[12],G_11_0}, p[12]); - grey g_14_0 (G_14_0, {g[14],G_13_0}, p[14]); - grey g_16_0 (G_16_0, {g[16],G_15_0}, p[16]); - grey g_18_0 (G_18_0, {g[18],G_17_0}, p[18]); - grey g_20_0 (G_20_0, {g[20],G_19_0}, p[20]); - grey g_22_0 (G_22_0, {g[22],G_21_0}, p[22]); - grey g_24_0 (G_24_0, {g[24],G_23_0}, p[24]); - grey g_26_0 (G_26_0, {g[26],G_25_0}, p[26]); - grey g_28_0 (G_28_0, {g[28],G_27_0}, p[28]); - grey g_30_0 (G_30_0, {g[30],G_29_0}, p[30]); - grey g_32_0 (G_32_0, {g[32],G_31_0}, p[32]); - grey g_34_0 (G_34_0, {g[34],G_33_0}, p[34]); - - // Final Stage: Apply c_k+1=G_k_0 - assign c[1]=g[0]; - assign c[2]=G_1_0; - assign c[3]=G_2_0; - assign c[4]=G_3_0; - assign c[5]=G_4_0; - assign c[6]=G_5_0; - assign c[7]=G_6_0; - assign c[8]=G_7_0; - assign c[9]=G_8_0; - - assign c[10]=G_9_0; - assign c[11]=G_10_0; - assign c[12]=G_11_0; - assign c[13]=G_12_0; - assign c[14]=G_13_0; - assign c[15]=G_14_0; - assign c[16]=G_15_0; - assign c[17]=G_16_0; - - assign c[18]=G_17_0; - assign c[19]=G_18_0; - assign c[20]=G_19_0; - assign c[21]=G_20_0; - assign c[22]=G_21_0; - assign c[23]=G_22_0; - assign c[24]=G_23_0; - assign c[25]=G_24_0; - - assign c[26]=G_25_0; - assign c[27]=G_26_0; - assign c[28]=G_27_0; - assign c[29]=G_28_0; - assign c[30]=G_29_0; - assign c[31]=G_30_0; - assign c[32]=G_31_0; - assign c[33]=G_32_0; - - assign c[34]=G_33_0; - assign c[35]=G_34_0; - assign c[36]=G_35_0; - -endmodule // ladner_fischer36 - -// Brent-Kung Prefix Adder -module bk6 (cout, sum, a, b, cin); - - input logic [5:0] a, b; - input logic cin; - - output logic [5:0] sum; - output logic cout; - - logic [6:0] p,g; - logic [5:0] c; - - // pre-computation - assign p={a^b,1'b0}; - assign g={a&b, cin}; - - // prefix tree - brent_kung prefix_tree(c, p[5:0], g[5:0]); - - // post-computation - assign sum=p[6:1]^c; - assign cout=g[6]|(p[6]&c[5]); - -endmodule // bk6 - -module brent_kung (c, p, g); - - input logic [5:0] p; - input logic [5:0] g; - - output logic [6:1] c; - - // parallel-prefix, Brent-Kung - // Stage 1: Generates G/P pairs that span 1 bits - grey b_1_0 (G_1_0, {g[1],g[0]}, p[1]); - black b_3_2 (G_3_2, P_3_2, {g[3],g[2]}, {p[3],p[2]}); - black b_5_4 (G_5_4, P_5_4, {g[5],g[4]}, {p[5],p[4]}); - - // Stage 2: Generates G/P pairs that span 2 bits - grey g_3_0 (G_3_0, {G_3_2,G_1_0}, P_3_2); - - // Stage 3: Generates G/P pairs that span 4 bits - - // Stage 4: Generates G/P pairs that span 2 bits - grey g_5_0 (G_5_0, {G_5_4,G_3_0}, P_5_4); - - // Last grey cell stage - grey g_2_0 (G_2_0, {g[2],G_1_0}, p[2]); - grey g_4_0 (G_4_0, {g[4],G_3_0}, p[4]); - - // Final Stage: Apply c_k+1=G_k_0 - assign c[1]=g[0]; - assign c[2]=G_1_0; - assign c[3]=G_2_0; - assign c[4]=G_3_0; - assign c[5]=G_4_0; - assign c[6]=G_5_0; - -endmodule // brent_kung - -// Black cell -module black (gout, pout, gin, pin); - - input logic [1:0] gin, pin; - output logic gout, pout; - - assign pout=pin[1]&pin[0]; - assign gout=gin[1]|(pin[1]&gin[0]); - -endmodule // black - -// Grey cell -module grey (gout, gin, pin); - - input logic [1:0] gin; - input logic pin; - output logic gout; - - assign gout=gin[1]|(pin&gin[0]); - -endmodule // grey - -// reduced Black cell -module rblk (hout, iout, gin, pin); - - input logic [1:0] gin, pin; - output logic hout, iout; - - assign iout=pin[1]&pin[0]; - assign hout=gin[1]|gin[0]; - -endmodule - -// reduced Grey cell -module rgry (hout, gin); - - input logic [1:0] gin; - output logic hout; - - assign hout=gin[1]|gin[0]; - -endmodule // rgry - +// LZD module lz2 (P, V, B0, B1); input logic B0; @@ -754,6 +456,8 @@ module lz32 (ZP, ZV, B); endmodule // lz32 +// FSM Control for Integer Divider + module fsm32 (en, state0, done, divdone, otfzero, start, error, NumIter, clk, reset); diff --git a/wally-pipelined/src/muldiv/div/divide4x64.sv b/wally-pipelined/src/muldiv/div/divide4x64.sv index 0cb6b0554..2f56f0eb7 100755 --- a/wally-pipelined/src/muldiv/div/divide4x64.sv +++ b/wally-pipelined/src/muldiv/div/divide4x64.sv @@ -51,8 +51,9 @@ module int64div (Q, done, divdone, rem0, div0, N, D, clk, reset, start); // #iter: N = m+v+s = m+(s+2) = m+2+s (mod k = 0) // v = 2 since \rho < 1 (add 4 to make sure its a ceil) - bk8 cpa1 (co1, Num, {2'b0, P}, - {5'h0, shiftResult, ~shiftResult, 1'b0}, 1'b0); + adder #(8) cpa1 ({2'b0, P}, + {5'h0, shiftResult, ~shiftResult, 1'b0}, + Num); // Determine whether need to add just Q/Rem assign shiftResult = P[0]; @@ -71,7 +72,7 @@ module int64div (Q, done, divdone, rem0, div0, N, D, clk, reset, start); flopr #(1) regc (~clk, reset, otfzerov, otfzero); flopr #(1) regd (~clk, reset, enablev, enable); flopr #(1) rege (~clk, reset, state0v, state0); - + // To obtain a correct remainder the last bit of the // quotient has to be aligned with a radix-r boundary. // Since the quotient is in the range 1/2 < q < 2 (one @@ -161,10 +162,10 @@ module divide4x64 (Q, rem0, quotient, op1, op2, clk, reset, state0, otfzero, enable, Qstar, QMstar); // Correction and generation of Remainder - add68 cpa2 (cout1, rem1, SumN2[67:0], CarryN2[67:0], 1'b0); + adder #(68) cpa2 (SumN2[67:0], CarryN2[67:0], rem1); // Add back +D as correction csa #(68) csa2 (CarryN2[67:0], SumN2[67:0], divi1, SumR, CarryR); - add68 cpa3 (cout2, rem2, SumR, CarryR, 1'b0); + adder #(68) cpa3 (SumR, CarryR, rem2); // Choose remainder (Rem or Rem+D) mux2 #(68) mx6 (rem1, rem2, rem1[67], rem3); // Choose correct Q or QM @@ -177,22 +178,25 @@ endmodule // divide4x64 module ls_control (quot, Qin, QMin, CshiftQ, CshiftQM); - input logic [3:0] quot; + input logic [3:0] quot; - output logic [1:0] Qin; - output logic [1:0] QMin; - output logic CshiftQ; - output logic CshiftQM; + output logic [1:0] Qin; + output logic [1:0] QMin; + output logic CshiftQ; + output logic CshiftQM; - assign Qin[1] = (quot[1]) | (quot[3]) | (quot[0]); - assign Qin[0] = (quot[1]) | (quot[2]); - assign QMin[1] = (quot[1]) | (!quot[3]&!quot[2]&!quot[1]&!quot[0]); - assign QMin[0] = (quot[3]) | (quot[0]) | - (!quot[3]&!quot[2]&!quot[1]&!quot[0]); - assign CshiftQ = (quot[1]) | (quot[0]); - assign CshiftQM = (quot[3]) | (quot[2]); + // Load/Store Control for OTF + assign Qin[1] = (quot[1]) | (quot[3]) | (quot[0]); + assign Qin[0] = (quot[1]) | (quot[2]); + assign QMin[1] = (quot[1]) | (!quot[3]&!quot[2]&!quot[1]&!quot[0]); + assign QMin[0] = (quot[3]) | (quot[0]) | + (!quot[3]&!quot[2]&!quot[1]&!quot[0]); + assign CshiftQ = (quot[1]) | (quot[0]); + assign CshiftQM = (quot[3]) | (quot[2]); - endmodule +endmodule + +// On-the-fly Conversion per Ercegovac/Lang module otf #(parameter WIDTH=8) (Qin, QMin, CshiftQ, CshiftQM, clk, reset, enable, R2Q, R1Q); @@ -219,44 +223,44 @@ module otf #(parameter WIDTH=8) assign Qstar = R2Q; assign QMstar = R1Q; - endmodule // otf8 +endmodule // otf8 - module adder #(parameter WIDTH=8) (input logic [WIDTH-1:0] a, b, - output logic [WIDTH-1:0] y); +module adder #(parameter WIDTH=8) (input logic [WIDTH-1:0] a, b, + output logic [WIDTH-1:0] y); - assign y = a + b; + assign y = a + b; - endmodule // adder +endmodule // adder - module fa (input logic a, b, c, output logic sum, carry); +module fa (input logic a, b, c, output logic sum, carry); - assign sum = a^b^c; - assign carry = a&b|a&c|b&c; + assign sum = a^b^c; + assign carry = a&b|a&c|b&c; - endmodule // fa +endmodule // fa - module csa #(parameter WIDTH=8) (input logic [WIDTH-1:0] a, b, c, - output logic [WIDTH-1:0] sum, carry); +module csa #(parameter WIDTH=8) (input logic [WIDTH-1:0] a, b, c, + output logic [WIDTH-1:0] sum, carry); - logic [WIDTH:0] carry_temp; - genvar i; - generate - for (i=0;i