From 394051c02fd17a54cc1ee9f0697dbff3e4f3e2c5 Mon Sep 17 00:00:00 2001 From: Thomas Fleming Date: Wed, 3 Mar 2021 17:13:45 -0500 Subject: [PATCH 01/16] Begin hardware page table walker --- wally-pipelined/src/ebu/ahblite.sv | 4 +- wally-pipelined/src/ebu/pagetablewalker.sv | 102 +++++++++++++++++++++ 2 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 wally-pipelined/src/ebu/pagetablewalker.sv diff --git a/wally-pipelined/src/ebu/ahblite.sv b/wally-pipelined/src/ebu/ahblite.sv index 10aa1f1a..d91acc5c 100644 --- a/wally-pipelined/src/ebu/ahblite.sv +++ b/wally-pipelined/src/ebu/ahblite.sv @@ -89,8 +89,8 @@ module ahblite ( else BusState <= #1 NextBusState; always_comb - case (BusState) - IDLE: if (MemReadM) NextBusState = MEMREAD; // Memory has pirority over instructions + case (BusState) + IDLE: if (MemReadM) NextBusState = MEMREAD; // Memory has priority over instructions else if (MemWriteM) NextBusState = MEMWRITE; else if (InstrReadF) NextBusState = INSTRREAD; else NextBusState = IDLE; diff --git a/wally-pipelined/src/ebu/pagetablewalker.sv b/wally-pipelined/src/ebu/pagetablewalker.sv new file mode 100644 index 00000000..4b42a4c9 --- /dev/null +++ b/wally-pipelined/src/ebu/pagetablewalker.sv @@ -0,0 +1,102 @@ +/////////////////////////////////////////// +// ahblite.sv +// +// Written: tfleming@hmc.edu 2 March 2021 +// Modified: +// +// Purpose: Page Table Walker +// Part of the Memory Management Unit (MMU) +// +// 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 pagetablewalker ( + input logic clk, reset, + + input logic [`XLEN-1:0] satp, + + input logic TLBMissF, + input logic [`XLEN-1:0] TranslationVAdr, + + input logic HCLK, HRESETn, + + input logic HREADY, + + output logic [`XLEN-1:0] PageTableEntryF, + output logic TranslationComplete +); + + /* + generate + if (`XLEN == 32) begin + logic Sv_Mode = satp[31] + end else begin + logic Sv_Mode [3:0] = satp[63:60] + end + endgenerate + */ + + logic Sv_Mode = satp[31]; + logic BasePageTablePPN [21:0] = satp[21:0]; + + logic VPN1 [9:0] = TranslationVAdr[31:22]; + logic VPN0 [9:0] = TranslationVAdr[21:12]; // *** could optimize by not passing offset? + + logic TranslationPAdr [33:0]; + + typedef enum {IDLE, LEVEL1, LEVEL0, LEAF, FAULT} statetype; + statetype WalkerState, NextWalkerState; + + always_ff @(posedge HCLK, negedge HRESETn) + if (~HRESETn) WalkerState <= #1 IDLE; + else WalkerState <= #1 NextWalkerState; + + always_comb begin + NextWalkerState = 'X; + case (WalkerState) + IDLE: if (TLBMissM) NextWalkerState = LEVEL1; + else NextWalkerState = IDLE; + LEVEL1: if (HREADY && ValidEntry) NextWalkerState = LEVEL0; + else if (HREADY) NextWalkerState = FAULT; + else NextWalkerState = LEVEL1; + LEVEL2: if (HREADY && ValidEntry) NextWalkerState = LEAF; + else if (HREADY) NextWalkerState = FAULT; + else NextWalkerState = LEVEL2; + LEAF: NextWalkerState = IDLE; + endcase + end + + always_ff @(posedge HCLK, negedge HRESETn) + if (~HRESETn) begin + TranslationPAdr <= '0; + PageTableEntryF <= '0; + TranslationComplete <= '0; + end else begin + // default values + case (NextWalkerState) + LEVEL1: TranslationPAdr <= {BasePageTablePPN, VPN1, 2'b00}; + LEVEL2: TranslationPAdr <= {CurrentPPN, VPN0, 2'b00}; + LEAF: PageTableEntryF <= CurrentPageTableEntry; + TranslationComplete <= '1; + end + + assign #1 Translate = (NextWalkerState = LEVEL1); + + +endmodule \ No newline at end of file From 7e11317a2d8090fa325d21941d6ccfa0206e18d8 Mon Sep 17 00:00:00 2001 From: Thomas Fleming Date: Fri, 5 Mar 2021 01:22:53 -0500 Subject: [PATCH 04/16] Export SATP_REGW from csrs to MMU modules --- wally-pipelined/src/dmem/dmem.sv | 10 ++------ wally-pipelined/src/ebu/ahblite.sv | 5 +++- ...etablewalker.sv => pagetablewalker.sv_dev} | 24 +++++++++++-------- wally-pipelined/src/ifu/ifu.sv | 8 ++----- wally-pipelined/src/privileged/csr.sv | 2 ++ wally-pipelined/src/privileged/csrs.sv | 4 +++- wally-pipelined/src/privileged/privileged.sv | 1 + .../src/wally/wallypipelinedhart.sv | 6 +++++ 8 files changed, 34 insertions(+), 26 deletions(-) rename wally-pipelined/src/ebu/{pagetablewalker.sv => pagetablewalker.sv_dev} (84%) diff --git a/wally-pipelined/src/dmem/dmem.sv b/wally-pipelined/src/dmem/dmem.sv index aa4327c2..679fc884 100644 --- a/wally-pipelined/src/dmem/dmem.sv +++ b/wally-pipelined/src/dmem/dmem.sv @@ -51,25 +51,19 @@ module dmem ( output logic StoreMisalignedFaultM, StoreAccessFaultM, // TLB management //input logic [`XLEN-1:0] PageTableEntryM, + input logic [`XLEN-1:0] SATP_REGW, //input logic DTLBWriteM, DTLBFlushM, - // *** satp value will come from CSRs - // input logic [`XLEN-1:0] SATP, output logic DTLBMissM, DTLBHitM ); logic SquashSCM; - // Initially no MMU - // *** temporary hack until we can figure out how to get actual satp value - // from priv unit -- Thomas F - logic [`XLEN-1:0] SATP = '0; // *** temporary hack until walker is hooked up -- Thomas F logic [`XLEN-1:0] PageTableEntryM = '0; logic DTLBFlushM = '0; logic DTLBWriteM = '0; - tlb #(3) dtlb(clk, reset, SATP, MemAdrM, PageTableEntryM, DTLBWriteM, + tlb #(3) dtlb(clk, reset, SATP_REGW, MemAdrM, PageTableEntryM, DTLBWriteM, DTLBFlushM, MemPAdrM, DTLBMissM, DTLBHitM); - //assign MemPAdrM = MemAdrM; // Determine if an Unaligned access is taking place always_comb diff --git a/wally-pipelined/src/ebu/ahblite.sv b/wally-pipelined/src/ebu/ahblite.sv index d91acc5c..bc4e6d1b 100644 --- a/wally-pipelined/src/ebu/ahblite.sv +++ b/wally-pipelined/src/ebu/ahblite.sv @@ -44,6 +44,8 @@ module ahblite ( input logic MemReadM, MemWriteM, input logic [`XLEN-1:0] WriteDataM, input logic [1:0] MemSizeM, + // Signals from MMU *** + // MMUPAdr; // Return from bus output logic [`XLEN-1:0] ReadDataW, // AHB-Lite external signals @@ -64,6 +66,7 @@ module ahblite ( output logic HWRITED, // Stalls output logic InstrStall,/*InstrUpdate, */DataStall + // *** add a chip-level ready signal as part of handshake ); logic GrantData; @@ -75,7 +78,7 @@ module ahblite ( assign HCLK = clk; assign HRESETn = ~reset; - // *** initially support HABW = XLEN + // *** initially support AHBW = XLEN // track bus state // Data accesses have priority over instructions. However, if a data access comes diff --git a/wally-pipelined/src/ebu/pagetablewalker.sv b/wally-pipelined/src/ebu/pagetablewalker.sv_dev similarity index 84% rename from wally-pipelined/src/ebu/pagetablewalker.sv rename to wally-pipelined/src/ebu/pagetablewalker.sv_dev index 4b42a4c9..eaed0948 100644 --- a/wally-pipelined/src/ebu/pagetablewalker.sv +++ b/wally-pipelined/src/ebu/pagetablewalker.sv_dev @@ -1,5 +1,5 @@ /////////////////////////////////////////// -// ahblite.sv +// pagetablewalker.sv // // Written: tfleming@hmc.edu 2 March 2021 // Modified: @@ -29,16 +29,17 @@ module pagetablewalker ( input logic clk, reset, - input logic [`XLEN-1:0] satp, + input logic [`XLEN-1:0] SATP_REGW, - input logic TLBMissF, + input logic ITLBMissF, DTLBMissM, input logic [`XLEN-1:0] TranslationVAdr, input logic HCLK, HRESETn, input logic HREADY, - output logic [`XLEN-1:0] PageTableEntryF, + output logic [`XLEN-1:0] PageTableEntryF, PageTableEntryM, + output logic ITLBWriteF, DTLBWriteM, output logic TranslationComplete ); @@ -52,15 +53,15 @@ module pagetablewalker ( endgenerate */ - logic Sv_Mode = satp[31]; - logic BasePageTablePPN [21:0] = satp[21:0]; + logic Sv_Mode = SATP_REGW[31]; + logic BasePageTablePPN [21:0] = SATP_REGW[21:0]; logic VPN1 [9:0] = TranslationVAdr[31:22]; logic VPN0 [9:0] = TranslationVAdr[21:12]; // *** could optimize by not passing offset? logic TranslationPAdr [33:0]; - typedef enum {IDLE, LEVEL1, LEVEL0, LEAF, FAULT} statetype; + typedef enum {IDLE, DATA_LEVEL1, DATA_LEVEL0, DATA_LEAF, DATA FAULT} statetype; statetype WalkerState, NextWalkerState; always_ff @(posedge HCLK, negedge HRESETn) @@ -92,11 +93,14 @@ module pagetablewalker ( case (NextWalkerState) LEVEL1: TranslationPAdr <= {BasePageTablePPN, VPN1, 2'b00}; LEVEL2: TranslationPAdr <= {CurrentPPN, VPN0, 2'b00}; - LEAF: PageTableEntryF <= CurrentPageTableEntry; - TranslationComplete <= '1; + LEAF: begin + PageTableEntryF <= CurrentPageTableEntry; + TranslationComplete <= '1; + end + endcase end - assign #1 Translate = (NextWalkerState = LEVEL1); + assign #1 Translate = (NextWalkerState == LEVEL1); endmodule \ No newline at end of file diff --git a/wally-pipelined/src/ifu/ifu.sv b/wally-pipelined/src/ifu/ifu.sv index 88e4f0be..fe275bc0 100644 --- a/wally-pipelined/src/ifu/ifu.sv +++ b/wally-pipelined/src/ifu/ifu.sv @@ -54,9 +54,8 @@ module ifu ( output logic [`XLEN-1:0] InstrMisalignedAdrM, // TLB management //input logic [`XLEN-1:0] PageTableEntryF, + input logic [`XLEN-1:0] SATP_REGW, //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 @@ -71,14 +70,11 @@ module ifu ( logic [31:0] InstrF, InstrRawD, InstrE, InstrW; logic [31:0] nop = 32'h00000013; // instruction for NOP - // *** temporary hack until we can figure out how to get actual satp value - // from priv unit -- Thomas F - logic [`XLEN-1:0] SATP = '0; // *** temporary hack until walker is hooked up -- Thomas F logic [`XLEN-1:0] PageTableEntryF = '0; logic ITLBFlushF = '0; logic ITLBWriteF = '0; - tlb #(3) itlb(clk, reset, SATP, PCF, PageTableEntryF, ITLBWriteF, ITLBFlushF, + tlb #(3) itlb(clk, reset, SATP_REGW, PCF, PageTableEntryF, ITLBWriteF, ITLBFlushF, InstrPAdrF, ITLBMissF, ITLBHitF); // *** put memory interface on here, InstrF becomes output diff --git a/wally-pipelined/src/privileged/csr.sv b/wally-pipelined/src/privileged/csr.sv index f1f16ac9..5d3c24a4 100644 --- a/wally-pipelined/src/privileged/csr.sv +++ b/wally-pipelined/src/privileged/csr.sv @@ -40,6 +40,7 @@ module csr ( output logic STATUS_SPP, STATUS_TSR, output logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW, UEPC_REGW, UTVEC_REGW, STVEC_REGW, MTVEC_REGW, output logic [`XLEN-1:0] MEDELEG_REGW, MIDELEG_REGW, SEDELEG_REGW, SIDELEG_REGW, + output logic [`XLEN-1:0] SATP_REGW, output logic [11:0] MIP_REGW, MIE_REGW, output logic STATUS_MIE, STATUS_SIE, input logic [4:0] SetFflagsM, @@ -126,6 +127,7 @@ module csr ( assign MIDELEG_REGW = 0; assign SEDELEG_REGW = 0; assign SIDELEG_REGW = 0; + assign SATP_REGW = 0; assign MIP_REGW = 0; assign MIE_REGW = 0; assign STATUS_MIE = 0; diff --git a/wally-pipelined/src/privileged/csrs.sv b/wally-pipelined/src/privileged/csrs.sv index 8301eed5..8f688cc1 100644 --- a/wally-pipelined/src/privileged/csrs.sv +++ b/wally-pipelined/src/privileged/csrs.sv @@ -48,6 +48,7 @@ module csrs #(parameter output logic [`XLEN-1:0] CSRSReadValM, SEPC_REGW, STVEC_REGW, output logic [31:0] SCOUNTEREN_REGW, output logic [`XLEN-1:0] SEDELEG_REGW, SIDELEG_REGW, + output logic [`XLEN-1:0] SATP_REGW, input logic [11:0] SIP_REGW, SIE_REGW, output logic WriteSSTATUSM, output logic IllegalCSRSAccessM @@ -63,7 +64,7 @@ module csrs #(parameter logic WriteSTVECM; logic WriteSSCRATCHM, WriteSEPCM; logic WriteSCAUSEM, WriteSTVALM, WriteSATPM, WriteSCOUNTERENM; - logic [`XLEN-1:0] SSCRATCH_REGW, SCAUSE_REGW, STVAL_REGW, SATP_REGW; + logic [`XLEN-1:0] SSCRATCH_REGW, SCAUSE_REGW, STVAL_REGW; assign WriteSSTATUSM = CSRSWriteM && (CSRAdrM == SSTATUS); assign WriteSTVECM = CSRSWriteM && (CSRAdrM == STVEC); @@ -123,6 +124,7 @@ module csrs #(parameter assign SEDELEG_REGW = 0; assign SIDELEG_REGW = 0; assign SCOUNTEREN_REGW = 0; + assign SATP_REGW = 0; assign IllegalCSRSAccessM = 1; end endgenerate diff --git a/wally-pipelined/src/privileged/privileged.sv b/wally-pipelined/src/privileged/privileged.sv index 71b90586..a01fa557 100644 --- a/wally-pipelined/src/privileged/privileged.sv +++ b/wally-pipelined/src/privileged/privileged.sv @@ -44,6 +44,7 @@ module privileged ( input logic TimerIntM, ExtIntM, SwIntM, input logic [`XLEN-1:0] InstrMisalignedAdrM, MemAdrM, input logic [4:0] SetFflagsM, + output logic [`XLEN-1:0] SATP_REGW, output logic [2:0] FRM_REGW, input logic FlushD, FlushE, FlushM, StallD, StallW ); diff --git a/wally-pipelined/src/wally/wallypipelinedhart.sv b/wally-pipelined/src/wally/wallypipelinedhart.sv index ded4df3d..e2014653 100644 --- a/wally-pipelined/src/wally/wallypipelinedhart.sv +++ b/wally-pipelined/src/wally/wallypipelinedhart.sv @@ -88,8 +88,12 @@ module wallypipelinedhart ( logic SquashSCW; // memory management unit signals + logic ITLBWriteF, DTLBWriteM; logic ITLBMissF, ITLBHitF; logic DTLBMissM, DTLBHitM; + logic [`XLEN-1:0] SATP_REGW; + + logic [`XLEN-1:0] PageTableEntryF, PageTableEntryM; // bus interface to dmem logic MemReadM, MemWriteM; @@ -114,6 +118,8 @@ module wallypipelinedhart ( .MemSizeM(Funct3M[1:0]), .UnsignedLoadM(Funct3M[2]), .*); + // walker walker(.*); *** // can send addresses to ahblite, send out pagetablestall + // *** can connect to hazard unit // changing from this to the line above breaks the program. auipc at 104 fails; seems to be flushed. // Would need to insertinstruction as InstrD, not InstrF /*ahblite ebu( From 8c97143be60ed473fa5b775c5f8c515ebaa6f5bf Mon Sep 17 00:00:00 2001 From: Thomas Fleming Date: Fri, 5 Mar 2021 13:35:24 -0500 Subject: [PATCH 05/16] Place tlb parameters into constant header file --- .../config/busybear/wally-constants.vh | 31 +++++++++++ .../config/coremark/wally-constants.vh | 31 +++++++++++ .../config/rv32ic/wally-constants.vh | 31 +++++++++++ .../config/rv64ic/wally-constants.vh | 31 +++++++++++ .../config/rv64icfd/wally-constants.vh | 31 +++++++++++ wally-pipelined/src/mmu/tlb.sv | 54 +++++++++---------- 6 files changed, 181 insertions(+), 28 deletions(-) create mode 100644 wally-pipelined/config/busybear/wally-constants.vh create mode 100644 wally-pipelined/config/coremark/wally-constants.vh create mode 100644 wally-pipelined/config/rv32ic/wally-constants.vh create mode 100644 wally-pipelined/config/rv64ic/wally-constants.vh create mode 100644 wally-pipelined/config/rv64icfd/wally-constants.vh diff --git a/wally-pipelined/config/busybear/wally-constants.vh b/wally-pipelined/config/busybear/wally-constants.vh new file mode 100644 index 00000000..55fb4e94 --- /dev/null +++ b/wally-pipelined/config/busybear/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/config/coremark/wally-constants.vh b/wally-pipelined/config/coremark/wally-constants.vh new file mode 100644 index 00000000..55fb4e94 --- /dev/null +++ b/wally-pipelined/config/coremark/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/config/rv32ic/wally-constants.vh b/wally-pipelined/config/rv32ic/wally-constants.vh new file mode 100644 index 00000000..ffa26727 --- /dev/null +++ b/wally-pipelined/config/rv32ic/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 (sv32) +`define VPN_BITS 20 +`define PPN_BITS 22 +`define PA_BITS 34 diff --git a/wally-pipelined/config/rv64ic/wally-constants.vh b/wally-pipelined/config/rv64ic/wally-constants.vh new file mode 100644 index 00000000..55fb4e94 --- /dev/null +++ b/wally-pipelined/config/rv64ic/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/config/rv64icfd/wally-constants.vh b/wally-pipelined/config/rv64icfd/wally-constants.vh new file mode 100644 index 00000000..55fb4e94 --- /dev/null +++ b/wally-pipelined/config/rv64icfd/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/mmu/tlb.sv b/wally-pipelined/src/mmu/tlb.sv index 7be0f0b7..4d4e46a3 100644 --- a/wally-pipelined/src/mmu/tlb.sv +++ b/wally-pipelined/src/mmu/tlb.sv @@ -25,6 +25,7 @@ /////////////////////////////////////////// `include "wally-config.vh" +`include "wally-constants.vh" /** * sv32 specs @@ -57,7 +58,7 @@ module tlb #(parameter ENTRY_BITS = 3) ( input clk, reset, // Current value of satp CSR (from privileged unit) - input [`XLEN-1:0] SATP, // *** How do we get this? + input [`XLEN-1:0] SATP_REGW, // Virtual address input input [`XLEN-1:0] VirtualAddress, @@ -75,32 +76,29 @@ module tlb #(parameter ENTRY_BITS = 3) ( output TLBHit ); + logic SvMode; + generate - if (`XLEN == 32) begin: ARCH - localparam VPN_BITS = 20; - localparam PPN_BITS = 22; - localparam PA_BITS = 34; - - logic SvMode; - assign SvMode = SATP[31]; // *** change to an enum somehow? - end else begin: ARCH - localparam VPN_BITS = 27; - localparam PPN_BITS = 44; - localparam PA_BITS = 56; - - logic SvMode; // currently just a boolean whether translation enabled - assign SvMode = SATP[63]; // *** change to an enum somehow? + if (`XLEN == 32) begin + assign SvMode = SATP_REGW[31]; // *** change to an enum somehow? + end else begin + assign SvMode = SATP_REGW[63]; // currently just a boolean whether translation enabled end endgenerate + // *** If we want to support multiple virtual memory modes (ie sv39 AND sv48), + // we could have some muxes that control which parameters are current. + // Although then some of the signals are not big enough. But that's a problem + // for much later. + // Index (currently random) to write the next TLB entry logic [ENTRY_BITS-1:0] WriteIndex; // Sections of the virtual and physical addresses - logic [ARCH.VPN_BITS-1:0] VirtualPageNumber; - logic [ARCH.PPN_BITS-1:0] PhysicalPageNumber; - logic [11:0] PageOffset; - logic [ARCH.PA_BITS-1:0] PhysicalAddressFull; + logic [`VPN_BITS-1:0] VirtualPageNumber; + logic [`PPN_BITS-1:0] PhysicalPageNumber; + logic [11:0] PageOffset; + logic [`PA_BITS-1:0] PhysicalAddressFull; // Pattern and pattern location in the CAM logic [ENTRY_BITS-1:0] VPNIndex; @@ -111,7 +109,7 @@ module tlb #(parameter ENTRY_BITS = 3) ( // Page table entry matching the virtual address logic [`XLEN-1:0] PageTableEntry; - assign VirtualPageNumber = VirtualAddress[ARCH.VPN_BITS+11:12]; + assign VirtualPageNumber = VirtualAddress[`VPN_BITS+11:12]; assign PageOffset = VirtualAddress[11:0]; // Choose a read or write location to the entry list @@ -121,28 +119,28 @@ module tlb #(parameter ENTRY_BITS = 3) ( tlb_rand rdm(.*); tlb_ram #(ENTRY_BITS) ram(.*); - tlb_cam #(ENTRY_BITS, ARCH.VPN_BITS) cam(.*); + tlb_cam #(ENTRY_BITS, `VPN_BITS) cam(.*); always_comb begin - assign PhysicalPageNumber = PageTableEntry[ARCH.PPN_BITS+9:10]; + assign PhysicalPageNumber = PageTableEntry[`PPN_BITS+9:10]; if (TLBHit) begin assign PhysicalAddressFull = {PhysicalPageNumber, PageOffset}; end else begin - assign PhysicalAddressFull = 8'b0; // *** Actual behavior; disabled until walker functioning + assign PhysicalAddressFull = '0; // *** Actual behavior; disabled until walker functioning //assign PhysicalAddressFull = {2'b0, VirtualPageNumber, PageOffset} // *** pass through should be removed as soon as walker ready end end generate if (`XLEN == 32) begin - mux2 #(`XLEN) addressmux(VirtualAddress, PhysicalAddressFull[31:0], ARCH.SvMode, PhysicalAddress); + mux2 #(`XLEN) addressmux(VirtualAddress, PhysicalAddressFull[31:0], SvMode, PhysicalAddress); end else begin - mux2 #(`XLEN) addressmux(VirtualAddress, {8'b0, PhysicalAddressFull}, ARCH.SvMode, PhysicalAddress); + mux2 #(`XLEN) addressmux(VirtualAddress, {8'b0, PhysicalAddressFull}, SvMode, PhysicalAddress); end endgenerate - assign TLBMiss = ~TLBHit & ~(TLBWrite | TLBFlush) & ARCH.SvMode; + assign TLBMiss = ~TLBHit & ~(TLBWrite | TLBFlush) & SvMode; endmodule module tlb_ram #(parameter ENTRY_BITS = 3) ( @@ -217,13 +215,13 @@ module tlb_cam #(parameter ENTRY_BITS = 3, initial begin for (int i = 0; i < NENTRIES; i++) - ram[i] <= '0; + ram[i] = '0; end endmodule module tlb_rand #(parameter ENTRY_BITS = 3) ( - input clk, reset, + input clk, reset, output [ENTRY_BITS-1:0] WriteIndex ); From 42275e92edd3e0e3d0b1f6d96fb310b0f77fd19d Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 11 Mar 2021 00:11:31 -0500 Subject: [PATCH 06/16] Initial untested implementation of AMO instructions --- wally-pipelined/src/dmem/dmem.sv | 6 +- wally-pipelined/src/ebu/ahblite.sv | 50 +++++++++----- wally-pipelined/src/ebu/amoalu.sv | 66 +++++++++++++++++++ wally-pipelined/src/ieu/controller.sv | 63 +++++++++--------- wally-pipelined/src/ieu/ieu.sv | 2 +- wally-pipelined/src/uncore/dtim.sv | 2 +- .../src/wally/wallypipelinedhart.sv | 4 +- 7 files changed, 140 insertions(+), 53 deletions(-) create mode 100644 wally-pipelined/src/ebu/amoalu.sv diff --git a/wally-pipelined/src/dmem/dmem.sv b/wally-pipelined/src/dmem/dmem.sv index 547663fc..321d3838 100644 --- a/wally-pipelined/src/dmem/dmem.sv +++ b/wally-pipelined/src/dmem/dmem.sv @@ -37,7 +37,7 @@ module dmem ( input logic [2:0] Funct3M, //input logic [`XLEN-1:0] ReadDataW, input logic [`XLEN-1:0] WriteDataM, - input logic AtomicM, + input logic [1:0] AtomicM, output logic [`XLEN-1:0] MemPAdrM, output logic MemReadM, MemWriteM, output logic DataMisalignedM, @@ -98,8 +98,8 @@ module dmem ( logic ReservationValidM, ReservationValidW; logic lrM, scM, WriteAdrMatchM; - assign lrM = MemReadM && AtomicM; - assign scM = MemRWM[0] && AtomicM; + assign lrM = MemReadM && AtomicM[0]; + assign scM = MemRWM[0] && AtomicM[0]; assign WriteAdrMatchM = MemRWM[0] && (MemPAdrM[`XLEN-1:2] == ReservationPAdrW) && ReservationValidW; assign SquashSCM = scM && ~WriteAdrMatchM; always_comb begin // ReservationValidM (next valiue of valid reservation) diff --git a/wally-pipelined/src/ebu/ahblite.sv b/wally-pipelined/src/ebu/ahblite.sv index 07918cdb..2c840a0c 100644 --- a/wally-pipelined/src/ebu/ahblite.sv +++ b/wally-pipelined/src/ebu/ahblite.sv @@ -35,6 +35,8 @@ module ahblite ( input logic StallW, FlushW, // Load control input logic UnsignedLoadM, + input logic [1:0] AtomicM, + input logic [6:0] Funct7M, // Signals from Instruction Cache input logic [`XLEN-1:0] InstrPAdrF, // *** rename these to match block diagram input logic InstrReadF, @@ -68,7 +70,7 @@ module ahblite ( logic GrantData; logic [2:0] ISize; - logic [`AHBW-1:0] HRDATAMasked, ReadDataM, ReadDataPreW; + logic [`AHBW-1:0] HRDATAMasked, ReadDataM, ReadDataPreW, WriteData; logic IReady, DReady; logic CaptureDataM; @@ -81,17 +83,23 @@ module ahblite ( // Data accesses have priority over instructions. However, if a data access comes // while an instruction read is occuring, the instruction read finishes before // the data access can take place. - typedef enum {IDLE, MEMREAD, MEMWRITE, INSTRREAD, INSTRREADMEMPENDING} statetype; + typedef enum {IDLE, MEMREAD, MEMWRITE, INSTRREAD, INSTRREADMEMPENDING, ATOMICREAD, ATOMICWRITE} statetype; statetype BusState, NextBusState; flopenl #(.TYPE(statetype)) busreg(HCLK, ~HRESETn, 1'b1, NextBusState, IDLE, BusState); always_comb case (BusState) - IDLE: if (MemReadM) NextBusState = MEMREAD; // Memory has pirority over instructions + IDLE: if (AtomicM[1]) NextBusState = ATOMICREAD; + else if (MemReadM) NextBusState = MEMREAD; // Memory has pirority over instructions else if (MemWriteM) NextBusState = MEMWRITE; else if (InstrReadF) NextBusState = INSTRREAD; else NextBusState = IDLE; + ATOMICREAD: if (~HREADY) NextBusState = ATOMICREAD; + else NextBusState = ATOMICWRITE; + ATOMICWRITE: if (~HREADY) NextBusState = ATOMICWRITE; + else if (InstrReadF) NextBusState = INSTRREAD; + else NextBusState = IDLE; MEMREAD: if (~HREADY) NextBusState = MEMREAD; else if (InstrReadF) NextBusState = INSTRREAD; else NextBusState = IDLE; @@ -107,17 +115,14 @@ module ahblite ( endcase // stall signals - assign #2 DataStall = (NextBusState == MEMREAD) || (NextBusState == MEMWRITE) || (NextBusState == INSTRREADMEMPENDING); + assign #2 DataStall = (NextBusState == MEMREAD) || (NextBusState == MEMWRITE) || + (NextBusState == ATOMICREAD) || (NextBusState == ATOMICWRITE) || + (NextBusState == INSTRREADMEMPENDING); assign #1 InstrStall = (NextBusState == INSTRREAD); - - // DH 2/20/22: A cyclic path presently exists - // HREADY->NextBusState->GrantData->HSIZE->HSELUART->HREADY - // This is because the peripherals assert HREADY on the same cycle - // When memory is working, also fix the peripherals to respond on the subsequent cycle - // and this path should be fixed. - + // bus outputs - assign #1 GrantData = (NextBusState == MEMREAD) || (NextBusState == MEMWRITE); + assign #1 GrantData = (NextBusState == MEMREAD) || (NextBusState == MEMWRITE) || + (NextBusState == ATOMICREAD) || (NextBusState == ATOMICWRITE); assign #1 HADDR = (GrantData) ? MemPAdrM[31:0] : InstrPAdrF[31:0]; assign ISize = 3'b010; // 32 bit instructions for now; later improve for filling cache with full width; ignored on reads anyway assign #1 HSIZE = GrantData ? {1'b0, MemSizeM} : ISize; @@ -125,9 +130,9 @@ module ahblite ( assign HPROT = 4'b0011; // not used; see Section 3.7 assign HTRANS = (NextBusState != IDLE) ? 2'b10 : 2'b00; // NONSEQ if reading or writing, IDLE otherwise assign HMASTLOCK = 0; // no locking supported - assign HWRITE = (NextBusState == MEMWRITE); + assign HWRITE = (NextBusState == MEMWRITE) || (NextBusState == ATOMICWRITE); // delay write data by one cycle for - flop #(`XLEN) wdreg(HCLK, WriteDataM, HWDATA); // delay HWDATA by 1 cycle per spec; *** assumes AHBW = XLEN + flop #(`XLEN) wdreg(HCLK, WriteData, HWDATA); // delay HWDATA by 1 cycle per spec; *** assumes AHBW = XLEN // delay signals for subword writes flop #(3) adrreg(HCLK, HADDR[2:0], HADDRD); flop #(4) sizereg(HCLK, {UnsignedLoadM, HSIZE}, HSIZED); @@ -138,11 +143,24 @@ module ahblite ( assign InstrRData = HRDATA; assign ReadDataM = HRDATAMasked; // changed from W to M dh 2/7/2021 - assign CaptureDataM = (BusState == MEMREAD) && (NextBusState != MEMREAD); + assign CaptureDataM = ((BusState == MEMREAD) && (NextBusState != MEMREAD)) || + ((BusState == ATOMICREAD) && (NextBusState == ATOMICWRITE)); + // *** check if this introduces an unnecessary cycle of latency in memory accesses flopenr #(`XLEN) ReadDataPreWReg(clk, reset, CaptureDataM, ReadDataM, ReadDataPreW); // *** this may break when there is no instruction read after data read flopenr #(`XLEN) ReadDataWReg(clk, reset, ~StallW, ReadDataPreW, ReadDataW); + // Extract and sign-extend subwords if necessary subwordread swr(.*); -endmodule + // Handle AMO instructions if applicable + generate + if (`A_SUPPORTED) begin + logic [`XLEN-1:0] AMOResult; + amoalu amoalu(.a(HRDATA), .b(WriteDataM), .funct(Funct7M), .width(MemSizeM), + .result(AMOResult)); + mux2 #(`XLEN) wdmux(WriteDataM, AMOResult, AtomicM[1], WriteData); + end else + assign WriteData = WriteDataM; + endgenerate +endmodule diff --git a/wally-pipelined/src/ebu/amoalu.sv b/wally-pipelined/src/ebu/amoalu.sv new file mode 100644 index 00000000..59d9f692 --- /dev/null +++ b/wally-pipelined/src/ebu/amoalu.sv @@ -0,0 +1,66 @@ +/////////////////////////////////////////// +// amoalu.sv +// +// Written: David_Harris@hmc.edu 10 March 2021 +// Modified: +// +// Purpose: Performs AMO operations +// +// 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 amoalu ( + input logic [`XLEN-1:0] a, b, + input logic [6:0] funct, + input logic [1:0] width, + output logic [`XLEN-1:0] result); + + logic [`XLEN-1:0] y; + + // *** see how synthesis generates this and optimize more structurally if necessary to share hardware + // a single carry chain should be shared for + and the four min/max + // and the same mux can be used to select b for swap. + always_comb + case (funct[6:2]) + 5'b00001: y = b; // amoswap + 5'b00000: y = a + b; // amoadd + 5'b00100: y = a ^ b; // amoxor + 5'b01100: y = a & b; // amoand + 5'b01000: y = a | b; // amoor + 5'b10000: y = (a < b) ? a : b; // amomin + 5'b10100: y = (a >= b) ? a : b; // amomax + 5'b11000: y = ({1'b0, a} < {1'b0, b}) ? a : b; // amominu + 5'b11100: y = ({1'b0, a} >= {1'b0, b}) ? a : b; // amomaxu + default: y = 'bx; // undefined; *** could change to b for efficiency + endcase + + // sign extend if necessary + generate + if (`XLEN == 32) begin + assign result = y; + end else begin // `XLEN = 64 + always_comb + if (width == 2'b10) // sign-extend word-length operations + result = {{32{y[31]}}, y[31:0]}; + else result = y; + end + endgenerate + +endmodule + diff --git a/wally-pipelined/src/ieu/controller.sv b/wally-pipelined/src/ieu/controller.sv index dc4f16d5..cf8c3e17 100644 --- a/wally-pipelined/src/ieu/controller.sv +++ b/wally-pipelined/src/ieu/controller.sv @@ -48,7 +48,7 @@ module controller( input logic StallM, FlushM, output logic [1:0] MemRWM, output logic CSRReadM, CSRWriteM, PrivilegedM, - output logic AtomicM, + output logic [1:0] AtomicM, output logic [2:0] Funct3M, output logic RegWriteM, // for Hazard Unit // Writeback stage control signals @@ -65,6 +65,8 @@ module controller( logic [6:0] Funct7D; logic [4:0] Rs1D; + `define CTRLW 23 + // pipelined control signals logic RegWriteD, RegWriteE; logic [2:0] ResultSrcD, ResultSrcE, ResultSrcM; @@ -77,11 +79,11 @@ module controller( logic TargetSrcD, W64D, MulDivD; logic CSRZeroSrcD; logic CSRReadD; - logic AtomicD, AtomicE; + logic [1:0] AtomicD, AtomicE; logic CSRWriteD, CSRWriteE; logic InstrValidE, InstrValidM; logic PrivilegedD, PrivilegedE; - logic [21:0] ControlsD; + logic [`CTRLW-1:0] ControlsD; logic aluc3D; logic subD, sraD, sltD, sltuD; logic BranchTakenE; @@ -100,48 +102,47 @@ module controller( generate always_comb case(OpD) - // *** Atomic p. 132 assembly encodings, defs 48 // RegWrite_ImmSrc_ALUSrc_MemRW_ResultSrc_Branch_ALUOp_Jump_TargetSrc_W64_CSRRead_Privileged_MulDiv_Atomic_Illegal - 7'b0000000: ControlsD = 22'b0_000_00_00_000_0_00_0_0_0_0_0_0_0_1; // illegal instruction - 7'b0000011: ControlsD = 22'b1_000_01_10_001_0_00_0_0_0_0_0_0_0_0; // lw - 7'b0001111: ControlsD = 22'b0_000_00_00_000_0_00_0_0_0_0_0_0_0_0; // fence = nop - 7'b0010011: ControlsD = 22'b1_000_01_00_000_0_10_0_0_0_0_0_0_0_0; // I-type ALU - 7'b0010111: ControlsD = 22'b1_100_11_00_000_0_00_0_0_0_0_0_0_0_0; // auipc + 7'b0000000: ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_0_0_00_1; // illegal instruction + 7'b0000011: ControlsD = `CTRLW'b1_000_01_10_001_0_00_0_0_0_0_0_0_00_0; // lw + 7'b0001111: ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_0_0_00_0; // fence = nop + 7'b0010011: ControlsD = `CTRLW'b1_000_01_00_000_0_10_0_0_0_0_0_0_00_0; // I-type ALU + 7'b0010111: ControlsD = `CTRLW'b1_100_11_00_000_0_00_0_0_0_0_0_0_00_0; // auipc 7'b0011011: if (`XLEN == 64) - ControlsD = 22'b1_000_01_00_000_0_10_0_0_1_0_0_0_0_0; // IW-type ALU for RV64i + ControlsD = `CTRLW'b1_000_01_00_000_0_10_0_0_1_0_0_0_00_0; // IW-type ALU for RV64i else - ControlsD = 22'b0_000_00_00_000_0_00_0_0_0_0_0_0_0_1; // non-implemented instruction - 7'b0100011: ControlsD = 22'b0_001_01_01_000_0_00_0_0_0_0_0_0_0_0; // sw + ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_0_0_00_1; // non-implemented instruction + 7'b0100011: ControlsD = `CTRLW'b0_001_01_01_000_0_00_0_0_0_0_0_0_00_0; // sw 7'b0101111: if (`A_SUPPORTED) begin if (InstrD[31:27] == 5'b00010) - ControlsD = 22'b1_000_00_10_001_0_00_0_0_0_0_0_0_1_0; // lr + ControlsD = `CTRLW'b1_000_00_10_001_0_00_0_0_0_0_0_0_01_0; // lr else if (InstrD[31:27] == 5'b00011) - ControlsD = 22'b1_101_01_01_101_0_00_0_0_0_0_0_0_1_0; // sc + ControlsD = `CTRLW'b1_101_01_01_101_0_00_0_0_0_0_0_0_01_0; // sc else - ControlsD = 22'b0_000_00_00_000_0_00_0_0_0_0_0_0_1_0; // other atomic; decode later + ControlsD = `CTRLW'b1_101_00_11_001_0_00_0_0_0_0_0_0_10_0;; // amo end else - ControlsD = 22'b0_000_00_00_000_0_00_0_0_0_0_0_0_0_1; // non-implemented instruction + ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_0_0_00_1; // non-implemented instruction 7'b0110011: if (Funct7D == 7'b0000000 || Funct7D == 7'b0100000) - ControlsD = 22'b1_000_00_00_000_0_10_0_0_0_0_0_0_0_0; // R-type + ControlsD = `CTRLW'b1_000_00_00_000_0_10_0_0_0_0_0_0_00_0; // R-type else if (Funct7D == 7'b0000001 && `M_SUPPORTED) - ControlsD = 22'b1_000_00_00_100_0_00_0_0_0_0_0_1_0_0; // Multiply/Divide + ControlsD = `CTRLW'b1_000_00_00_100_0_00_0_0_0_0_0_1_00_0; // Multiply/Divide else - ControlsD = 22'b0_000_00_00_000_0_00_0_0_0_0_0_0_0_1; // non-implemented instruction - 7'b0110111: ControlsD = 22'b1_100_01_00_000_0_11_0_0_0_0_0_0_0_0; // lui + ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_0_0_00_1; // non-implemented instruction + 7'b0110111: ControlsD = `CTRLW'b1_100_01_00_000_0_11_0_0_0_0_0_0_00_0; // lui 7'b0111011: if ((Funct7D == 7'b0000000 || Funct7D == 7'b0100000) && `XLEN == 64) - ControlsD = 22'b1_000_00_00_000_0_10_0_0_1_0_0_0_0_0; // R-type W instructions for RV64i + ControlsD = `CTRLW'b1_000_00_00_000_0_10_0_0_1_0_0_0_00_0; // R-type W instructions for RV64i else if (Funct7D == 7'b0000001 && `M_SUPPORTED && `XLEN == 64) - ControlsD = 22'b1_000_00_00_100_0_00_0_0_1_0_0_1_0_0; // W-type Multiply/Divide + ControlsD = `CTRLW'b1_000_00_00_100_0_00_0_0_1_0_0_1_00_0; // W-type Multiply/Divide else - ControlsD = 22'b0_000_00_00_000_0_00_0_0_0_0_0_0_0_1; // non-implemented instruction - 7'b1100011: ControlsD = 22'b0_010_00_00_000_1_01_0_0_0_0_0_0_0_0; // beq - 7'b1100111: ControlsD = 22'b1_000_00_00_010_0_00_1_1_0_0_0_0_0_0; // jalr - 7'b1101111: ControlsD = 22'b1_011_00_00_010_0_00_1_0_0_0_0_0_0_0; // jal + ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_0_0_00_1; // non-implemented instruction + 7'b1100011: ControlsD = `CTRLW'b0_010_00_00_000_1_01_0_0_0_0_0_0_00_0; // beq + 7'b1100111: ControlsD = `CTRLW'b1_000_00_00_010_0_00_1_1_0_0_0_0_00_0; // jalr + 7'b1101111: ControlsD = `CTRLW'b1_011_00_00_010_0_00_1_0_0_0_0_0_00_0; // jal 7'b1110011: if (Funct3D == 3'b000) - ControlsD = 22'b0_000_00_00_000_0_00_0_0_0_0_1_0_0_0; // privileged; decoded further in priveleged modules + ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_1_0_00_0; // privileged; decoded further in priveleged modules else - ControlsD = 22'b1_000_00_00_011_0_00_0_0_0_1_0_0_0_0; // csrs - default: ControlsD = 22'b0_000_00_00_000_0_00_0_0_0_0_0_0_0_1; // non-implemented instruction + ControlsD = `CTRLW'b1_000_00_00_011_0_00_0_0_0_1_0_0_00_0; // csrs + default: ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_0_0_00_1; // non-implemented instruction endcase endgenerate @@ -173,7 +174,7 @@ module controller( endcase // Execute stage pipeline control register and logic - flopenrc #(26) controlregE(clk, reset, FlushE, ~StallE, + flopenrc #(27) controlregE(clk, reset, FlushE, ~StallE, {RegWriteD, ResultSrcD, MemRWD, JumpD, BranchD, ALUControlD, ALUSrcAD, ALUSrcBD, TargetSrcD, CSRReadD, CSRWriteD, PrivilegedD, Funct3D, W64D, MulDivD, AtomicD, 1'b1}, {RegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUControlE, ALUSrcAE, ALUSrcBE, TargetSrcE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, W64E, MulDivE, AtomicE, InstrValidE}); @@ -196,7 +197,7 @@ module controller( assign MemReadE = MemRWE[1]; // Memory stage pipeline control register - flopenrc #(14) controlregM(clk, reset, FlushM, ~StallM, + flopenrc #(15) controlregM(clk, reset, FlushM, ~StallM, {RegWriteE, ResultSrcE, MemRWE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, AtomicE, InstrValidE}, {RegWriteM, ResultSrcM, MemRWM, CSRReadM, CSRWriteM, PrivilegedM, Funct3M, AtomicM, InstrValidM}); diff --git a/wally-pipelined/src/ieu/ieu.sv b/wally-pipelined/src/ieu/ieu.sv index d021bca6..f408fbd9 100644 --- a/wally-pipelined/src/ieu/ieu.sv +++ b/wally-pipelined/src/ieu/ieu.sv @@ -43,7 +43,7 @@ module ieu ( input logic DataAccessFaultM, input logic SquashSCW, output logic [1:0] MemRWM, - output logic AtomicM, + output logic [1:0] AtomicM, output logic [`XLEN-1:0] MemAdrM, WriteDataM, output logic [`XLEN-1:0] SrcAM, output logic [2:0] Funct3M, diff --git a/wally-pipelined/src/uncore/dtim.sv b/wally-pipelined/src/uncore/dtim.sv index 42ae7fbc..5d3f47e3 100644 --- a/wally-pipelined/src/uncore/dtim.sv +++ b/wally-pipelined/src/uncore/dtim.sv @@ -59,7 +59,7 @@ module dtim #(parameter BASE=0, RANGE = 65535) ( busycount <= 0; HREADYTim <= #1 0; end else if (~HREADYTim) begin - if (busycount == 2) begin // TIM latency, for testing purposes + if (busycount == 2) begin // TIM latency, for testing purposes. *** test with different values HREADYTim <= #1 1; end else begin busycount <= busycount + 1; diff --git a/wally-pipelined/src/wally/wallypipelinedhart.sv b/wally-pipelined/src/wally/wallypipelinedhart.sv index 3c8b25c3..da4abad2 100644 --- a/wally-pipelined/src/wally/wallypipelinedhart.sv +++ b/wally-pipelined/src/wally/wallypipelinedhart.sv @@ -60,7 +60,8 @@ module wallypipelinedhart ( // new signals that must connect through DP logic MulDivE, W64E; - logic CSRReadM, CSRWriteM, PrivilegedM, AtomicM; + logic CSRReadM, CSRWriteM, PrivilegedM; + logic [1:0] AtomicM; logic [`XLEN-1:0] SrcAE, SrcBE; logic [`XLEN-1:0] SrcAM; logic [2:0] Funct3E; @@ -113,6 +114,7 @@ module wallypipelinedhart ( //.InstrReadF(1'b0), //.InstrRData(InstrF), // hook up InstrF later .MemSizeM(Funct3M[1:0]), .UnsignedLoadM(Funct3M[2]), + .Funct7M(InstrM[31:25]), .*); // changing from this to the line above breaks the program. auipc at 104 fails; seems to be flushed. From a8b242a6ef997544c045f36246140f0acab65fb0 Mon Sep 17 00:00:00 2001 From: Noah Boorstin Date: Thu, 11 Mar 2021 06:45:14 +0000 Subject: [PATCH 08/16] busybear: account for CSR moving --- wally-pipelined/testbench/testbench-busybear.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wally-pipelined/testbench/testbench-busybear.sv b/wally-pipelined/testbench/testbench-busybear.sv index e4c9c9e3..ababf7e4 100644 --- a/wally-pipelined/testbench/testbench-busybear.sv +++ b/wally-pipelined/testbench/testbench-busybear.sv @@ -294,7 +294,7 @@ module testbench_busybear(); `CHECK_CSR(MTVEC) //`CHECK_CSR2(PMPADDR0, `CSRM) //`CHECK_CSR2(PMdut.PCFG0, `CSRM) - `CHECK_CSR2(SATP, `CSRS) + `CHECK_CSR(SATP) `CHECK_CSR2(SCAUSE, `CSRS) `CHECK_CSR(SCOUNTEREN) `CHECK_CSR(SEPC) From 1093b07670f32a7bc0f119b4d2df1e6793695887 Mon Sep 17 00:00:00 2001 From: Noah Boorstin Date: Thu, 11 Mar 2021 06:45:45 +0000 Subject: [PATCH 09/16] this is just a test for now, try to reimplement regression-wally in bash --- wally-pipelined/regression/regression-wally.sh | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100755 wally-pipelined/regression/regression-wally.sh diff --git a/wally-pipelined/regression/regression-wally.sh b/wally-pipelined/regression/regression-wally.sh new file mode 100755 index 00000000..12d39418 --- /dev/null +++ b/wally-pipelined/regression/regression-wally.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +check_test () { + output=$(./$1) + found=$(echo $output | grep -c "$2") + echo "$found" +} +echo "starting Imperas rv64ic" +coproc rv64 {(check_test "sim-wally-batch" "All tests ran without failures.")} +echo "starting busybear" +coproc busybear {(check_test "sim-busybear-batch" "loaded 100000 instructions")} +IFS= read -r -d '' -u "${rv64[0]}" rv64_out +[[ $rv64_out -eq 1 ]] && echo "rv64ic passed" || echo "rv64ic failed" +IFS= read -r -d '' -u "${busybear[0]}" busybear_out +[[ $busybear_out -eq 1 ]] && echo "busybear passed" || echo "busybear failed" + +#wait $(jobs -p) +[[ $rv64_out -eq 1 && $busybear_out -eq 1 ]] && echo "all passed" || echo "not all passed" From 81c14f899dc1ac921ddab1b5a735fcc92ceb757f Mon Sep 17 00:00:00 2001 From: Noah Boorstin Date: Thu, 11 Mar 2021 06:59:50 +0000 Subject: [PATCH 10/16] try adding delays to test regression script --- wally-pipelined/regression/regression-wally.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/wally-pipelined/regression/regression-wally.sh b/wally-pipelined/regression/regression-wally.sh index 12d39418..a5945ef7 100755 --- a/wally-pipelined/regression/regression-wally.sh +++ b/wally-pipelined/regression/regression-wally.sh @@ -5,8 +5,10 @@ check_test () { echo "$found" } echo "starting Imperas rv64ic" +sleep 1 coproc rv64 {(check_test "sim-wally-batch" "All tests ran without failures.")} echo "starting busybear" +sleep 1 coproc busybear {(check_test "sim-busybear-batch" "loaded 100000 instructions")} IFS= read -r -d '' -u "${rv64[0]}" rv64_out [[ $rv64_out -eq 1 ]] && echo "rv64ic passed" || echo "rv64ic failed" From aba54659bf063cc096395ac66acac3c9bde8c55c Mon Sep 17 00:00:00 2001 From: Noah Boorstin Date: Thu, 11 Mar 2021 07:32:31 +0000 Subject: [PATCH 11/16] test regression script: try adding verilator checking also --- wally-pipelined/regression/regression-wally.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/wally-pipelined/regression/regression-wally.sh b/wally-pipelined/regression/regression-wally.sh index a5945ef7..0ef76754 100755 --- a/wally-pipelined/regression/regression-wally.sh +++ b/wally-pipelined/regression/regression-wally.sh @@ -4,6 +4,9 @@ check_test () { found=$(echo $output | grep -c "$2") echo "$found" } +echo "checking verilator" +verilator_out=$(cd ..; ./lint-wally 2>&1) +[[ -z $verilator_out ]] && echo "verilator passed" || echo "verilator failed" echo "starting Imperas rv64ic" sleep 1 coproc rv64 {(check_test "sim-wally-batch" "All tests ran without failures.")} @@ -16,4 +19,4 @@ IFS= read -r -d '' -u "${busybear[0]}" busybear_out [[ $busybear_out -eq 1 ]] && echo "busybear passed" || echo "busybear failed" #wait $(jobs -p) -[[ $rv64_out -eq 1 && $busybear_out -eq 1 ]] && echo "all passed" || echo "not all passed" +[[ -z $verilator_out && $rv64_out -eq 1 && $busybear_out -eq 1 ]] && echo "all passed" || echo "not all passed" From 54fa16d7833860751b61b610f540d440d9a6c075 Mon Sep 17 00:00:00 2001 From: Noah Boorstin Date: Thu, 11 Mar 2021 12:25:20 -0500 Subject: [PATCH 12/16] test regression script: parallalize better --- wally-pipelined/regression/regression-wally.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/wally-pipelined/regression/regression-wally.sh b/wally-pipelined/regression/regression-wally.sh index 0ef76754..161db493 100755 --- a/wally-pipelined/regression/regression-wally.sh +++ b/wally-pipelined/regression/regression-wally.sh @@ -9,13 +9,13 @@ verilator_out=$(cd ..; ./lint-wally 2>&1) [[ -z $verilator_out ]] && echo "verilator passed" || echo "verilator failed" echo "starting Imperas rv64ic" sleep 1 -coproc rv64 {(check_test "sim-wally-batch" "All tests ran without failures.")} +exec 3< <(check_test "sim-wally-batch" "All tests ran without failures.") echo "starting busybear" sleep 1 -coproc busybear {(check_test "sim-busybear-batch" "loaded 100000 instructions")} -IFS= read -r -d '' -u "${rv64[0]}" rv64_out +exec 4< <(check_test "sim-busybear-batch" "loaded 100000 instructions") +rv64_out=$(cat <&3) [[ $rv64_out -eq 1 ]] && echo "rv64ic passed" || echo "rv64ic failed" -IFS= read -r -d '' -u "${busybear[0]}" busybear_out +busybear_out=$(cat <&4) [[ $busybear_out -eq 1 ]] && echo "busybear passed" || echo "busybear failed" #wait $(jobs -p) From 394b79b5de29fa37aa3c291d24ae010d95c57fa8 Mon Sep 17 00:00:00 2001 From: Noah Boorstin Date: Thu, 11 Mar 2021 12:40:29 -0500 Subject: [PATCH 13/16] add rv32ic regression test --- wally-pipelined/regression/sim-wally-rv32ic | 3 +++ 1 file changed, 3 insertions(+) create mode 100755 wally-pipelined/regression/sim-wally-rv32ic diff --git a/wally-pipelined/regression/sim-wally-rv32ic b/wally-pipelined/regression/sim-wally-rv32ic new file mode 100755 index 00000000..a254c824 --- /dev/null +++ b/wally-pipelined/regression/sim-wally-rv32ic @@ -0,0 +1,3 @@ +vsim -c < Date: Thu, 11 Mar 2021 12:57:54 -0500 Subject: [PATCH 14/16] test regression script: add commented out rv32ic tests --- wally-pipelined/regression/regression-wally.sh | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/wally-pipelined/regression/regression-wally.sh b/wally-pipelined/regression/regression-wally.sh index 161db493..39d82102 100755 --- a/wally-pipelined/regression/regression-wally.sh +++ b/wally-pipelined/regression/regression-wally.sh @@ -1,22 +1,34 @@ #!/usr/bin/env bash check_test () { - output=$(./$1) + output=$(timeout 2m ./"$1" 2>/dev/null) found=$(echo $output | grep -c "$2") echo "$found" } +echo "-----------------------" +echo "starting all regression tests!" +echo "note: this could take up to 3 minutes to run" +echo "-----------------------" echo "checking verilator" verilator_out=$(cd ..; ./lint-wally 2>&1) [[ -z $verilator_out ]] && echo "verilator passed" || echo "verilator failed" echo "starting Imperas rv64ic" sleep 1 exec 3< <(check_test "sim-wally-batch" "All tests ran without failures.") -echo "starting busybear" +#echo "starting Imperas rv32ic" +#sleep 1 +#exec 5< <(check_test "sim-wally-rv32ic" "All tests ran without failures.") +#echo "starting busybear" sleep 1 exec 4< <(check_test "sim-busybear-batch" "loaded 100000 instructions") +echo "-----------------------" +echo "waiting for tests to finish..." +echo "-----------------------" rv64_out=$(cat <&3) [[ $rv64_out -eq 1 ]] && echo "rv64ic passed" || echo "rv64ic failed" +#rv32_out=$(cat <&5) +#[[ $rv32_out -eq 1 ]] && echo "rv32ic passed" || echo "rv32ic failed" busybear_out=$(cat <&4) [[ $busybear_out -eq 1 ]] && echo "busybear passed" || echo "busybear failed" -#wait $(jobs -p) [[ -z $verilator_out && $rv64_out -eq 1 && $busybear_out -eq 1 ]] && echo "all passed" || echo "not all passed" +#[[ -z $verilator_out && $rv32_out -eq 1 && $rv64_out -eq 1 && $busybear_out -eq 1 ]] && echo "all passed" || echo "not all passed" From 865c1035991f5e838e980875f9fc91dcdaa7fc68 Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 11 Mar 2021 23:18:33 -0500 Subject: [PATCH 15/16] 64-bit AMO debugged --- wally-pipelined/src/ebu/ahblite.sv | 4 ++- wally-pipelined/src/ebu/amoalu.sv | 28 +++++++++++++------ wally-pipelined/src/ieu/controller.sv | 2 +- .../testbench/testbench-imperas.sv | 1 + 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/wally-pipelined/src/ebu/ahblite.sv b/wally-pipelined/src/ebu/ahblite.sv index 500ea492..ed353595 100644 --- a/wally-pipelined/src/ebu/ahblite.sv +++ b/wally-pipelined/src/ebu/ahblite.sv @@ -159,7 +159,9 @@ module ahblite ( generate if (`A_SUPPORTED) begin logic [`XLEN-1:0] AMOResult; - amoalu amoalu(.a(HRDATA), .b(WriteDataM), .funct(Funct7M), .width(MemSizeM), +// amoalu amoalu(.a(HRDATA), .b(WriteDataM), .funct(Funct7M), .width(MemSizeM), +// .result(AMOResult)); + amoalu amoalu(.srca(ReadDataPreW), .srcb(WriteDataM), .funct(Funct7M), .width(MemSizeM), .result(AMOResult)); mux2 #(`XLEN) wdmux(WriteDataM, AMOResult, AtomicM[1], WriteData); end else diff --git a/wally-pipelined/src/ebu/amoalu.sv b/wally-pipelined/src/ebu/amoalu.sv index 59d9f692..8acba98c 100644 --- a/wally-pipelined/src/ebu/amoalu.sv +++ b/wally-pipelined/src/ebu/amoalu.sv @@ -26,12 +26,15 @@ `include "wally-config.vh" module amoalu ( - input logic [`XLEN-1:0] a, b, + input logic [`XLEN-1:0] srca, srcb, input logic [6:0] funct, input logic [1:0] width, output logic [`XLEN-1:0] result); - logic [`XLEN-1:0] y; + logic [`XLEN-1:0] a, b, y; + + // *** can this be muxed into the regular ALU to avoid needing a second one? Only a good + // idea if the regular ALU is not the critical path // *** see how synthesis generates this and optimize more structurally if necessary to share hardware // a single carry chain should be shared for + and the four min/max @@ -43,22 +46,31 @@ module amoalu ( 5'b00100: y = a ^ b; // amoxor 5'b01100: y = a & b; // amoand 5'b01000: y = a | b; // amoor - 5'b10000: y = (a < b) ? a : b; // amomin - 5'b10100: y = (a >= b) ? a : b; // amomax - 5'b11000: y = ({1'b0, a} < {1'b0, b}) ? a : b; // amominu - 5'b11100: y = ({1'b0, a} >= {1'b0, b}) ? a : b; // amomaxu + 5'b10000: y = ($signed(a) < $signed(b)) ? a : b; // amomin + 5'b10100: y = ($signed(a) >= $signed(b)) ? a : b; // amomax + 5'b11000: y = ($unsigned(a) < $unsigned(b)) ? a : b; // amominu + 5'b11100: y = ($unsigned(a) >= $unsigned(b)) ? a : b; // amomaxu default: y = 'bx; // undefined; *** could change to b for efficiency endcase // sign extend if necessary generate if (`XLEN == 32) begin + assign a = srca; + assign b = srcb; assign result = y; end else begin // `XLEN = 64 always_comb - if (width == 2'b10) // sign-extend word-length operations + if (width == 2'b10) begin // sign-extend word-length operations + // *** it would be more efficient to look at carry out of bit 31 to determine comparisons than do this big mux on and b + a = {{32{srca[31]}}, srca[31:0]}; + b = {{32{srcb[31]}}, srcb[31:0]}; result = {{32{y[31]}}, y[31:0]}; - else result = y; + end else begin + a = srca; + b = srcb; + result = y; + end end endgenerate diff --git a/wally-pipelined/src/ieu/controller.sv b/wally-pipelined/src/ieu/controller.sv index cf8c3e17..a1be47ad 100644 --- a/wally-pipelined/src/ieu/controller.sv +++ b/wally-pipelined/src/ieu/controller.sv @@ -119,7 +119,7 @@ module controller( else if (InstrD[31:27] == 5'b00011) ControlsD = `CTRLW'b1_101_01_01_101_0_00_0_0_0_0_0_0_01_0; // sc else - ControlsD = `CTRLW'b1_101_00_11_001_0_00_0_0_0_0_0_0_10_0;; // amo + ControlsD = `CTRLW'b1_101_01_11_001_0_00_0_0_0_0_0_0_10_0;; // amo end else ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_0_0_00_1; // non-implemented instruction 7'b0110011: if (Funct7D == 7'b0000000 || Funct7D == 7'b0100000) diff --git a/wally-pipelined/testbench/testbench-imperas.sv b/wally-pipelined/testbench/testbench-imperas.sv index 50ef7c93..fd0c073e 100644 --- a/wally-pipelined/testbench/testbench-imperas.sv +++ b/wally-pipelined/testbench/testbench-imperas.sv @@ -38,6 +38,7 @@ module testbench(); //logic [31:0] InstrW; logic [`XLEN-1:0] meminit; string tests64a[] = '{ + "rv64a/WALLY-AMO", "2110", "rv64a/WALLY-LRSC", "2110" }; string tests64m[] = '{ From 56b690ccb9d52556473ae3f819f9633bbd028d92 Mon Sep 17 00:00:00 2001 From: David Harris Date: Fri, 12 Mar 2021 00:06:23 -0500 Subject: [PATCH 16/16] Drafted rv32a tests --- wally-pipelined/testbench/testbench-imperas.sv | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/wally-pipelined/testbench/testbench-imperas.sv b/wally-pipelined/testbench/testbench-imperas.sv index fd0c073e..54317656 100644 --- a/wally-pipelined/testbench/testbench-imperas.sv +++ b/wally-pipelined/testbench/testbench-imperas.sv @@ -191,6 +191,10 @@ string tests64iNOc[] = { "rv64i/WALLY-CSRRCI", "4000" }; + string tests32a[] = '{ + "rv64a/WALLY-AMO", "2110", + "rv64a/WALLY-LRSC", "2110" + }; string tests32m[] = '{ "rv32m/I-MUL-01", "2000", "rv32m/I-MULH-01", "2000", @@ -329,13 +333,14 @@ string tests32i[] = { if (`C_SUPPORTED) tests = {tests, tests64ic}; 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}; 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}; end string signame, memfilename;