From 5394e79ad7e85a91c187909c0d06760a8db0825f Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Fri, 11 Feb 2022 13:58:45 -0600 Subject: [PATCH 01/18] Fixed ila's config. --- fpga/constraints/debug2.xdc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fpga/constraints/debug2.xdc b/fpga/constraints/debug2.xdc index 19d0eae5f..9c3e5a5f6 100644 --- a/fpga/constraints/debug2.xdc +++ b/fpga/constraints/debug2.xdc @@ -553,9 +553,9 @@ set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe119] connect_debug_port u_ila_0/probe119 [get_nets [list wallypipelinedsoc/core/lsu/DTLBWriteM]] create_debug_port u_ila_0 probe -set_property port_width 11 [get_debug_ports u_ila_0/probe120] +set_property port_width 4 [get_debug_ports u_ila_0/probe120] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe120] -connect_debug_port u_ila_0/probe120 [get_nets [list {wallypipelinedsoc/core/lsu/VIRTMEM_SUPPORTED.lsuvirtmem/hptw/WalkerState[0]} {wallypipelinedsoc/core/lsu/VIRTMEM_SUPPORTED.lsuvirtmem/hptw/WalkerState[1]} {wallypipelinedsoc/core/lsu/VIRTMEM_SUPPORTED.lsuvirtmem/hptw/WalkerState[2]} {wallypipelinedsoc/core/lsu/VIRTMEM_SUPPORTED.lsuvirtmem/hptw/WalkerState[3]} {wallypipelinedsoc/core/lsu/VIRTMEM_SUPPORTED.lsuvirtmem/hptw/WalkerState[4]} {wallypipelinedsoc/core/lsu/VIRTMEM_SUPPORTED.lsuvirtmem/hptw/WalkerState[5]} {wallypipelinedsoc/core/lsu/VIRTMEM_SUPPORTED.lsuvirtmem/hptw/WalkerState[6]} {wallypipelinedsoc/core/lsu/VIRTMEM_SUPPORTED.lsuvirtmem/hptw/WalkerState[7]} {wallypipelinedsoc/core/lsu/VIRTMEM_SUPPORTED.lsuvirtmem/hptw/WalkerState[8]} {wallypipelinedsoc/core/lsu/VIRTMEM_SUPPORTED.lsuvirtmem/hptw/WalkerState[9]} {wallypipelinedsoc/core/lsu/VIRTMEM_SUPPORTED.lsuvirtmem/hptw/WalkerState[10]}]] +connect_debug_port u_ila_0/probe120 [get_nets [list {wallypipelinedsoc/core/lsu/VIRTMEM_SUPPORTED.lsuvirtmem/hptw/WalkerState[0]} {wallypipelinedsoc/core/lsu/VIRTMEM_SUPPORTED.lsuvirtmem/hptw/WalkerState[1]} {wallypipelinedsoc/core/lsu/VIRTMEM_SUPPORTED.lsuvirtmem/hptw/WalkerState[2]} {wallypipelinedsoc/core/lsu/VIRTMEM_SUPPORTED.lsuvirtmem/hptw/WalkerState[3]}]] create_debug_port u_ila_0 probe From fe896bff8e01a855d8ca126c8bf7431617839185 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Thu, 24 Mar 2022 23:47:28 -0500 Subject: [PATCH 02/18] Found a way to remove a bus input into MMU. PAdr can be made into VAdr by selecting the faulting virtual address when writing the DTLB. --- pipelined/src/ifu/ifu.sv | 3 +-- pipelined/src/lsu/lsu.sv | 7 +++---- pipelined/src/lsu/lsuvirtmen.sv | 19 +++++++++++++++---- pipelined/src/mmu/mmu.sv | 16 +++++----------- 4 files changed, 24 insertions(+), 21 deletions(-) diff --git a/pipelined/src/ifu/ifu.sv b/pipelined/src/ifu/ifu.sv index 6adc5ad2d..480556aaa 100644 --- a/pipelined/src/ifu/ifu.sv +++ b/pipelined/src/ifu/ifu.sv @@ -142,8 +142,7 @@ module ifu ( mmu #(.TLB_ENTRIES(`ITLB_ENTRIES), .IMMU(1)) immu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .PrivilegeModeW, .DisableTranslation(1'b0), - .PAdr(PCFExt[`PA_BITS-1:0]), - .VAdr(PCFSpill), + .VAdr(PCFExt), .Size(2'b10), .PTE(PTE), .PageTypeWriteVal(PageType), diff --git a/pipelined/src/lsu/lsu.sv b/pipelined/src/lsu/lsu.sv index 7442aea70..d5e5b2b35 100644 --- a/pipelined/src/lsu/lsu.sv +++ b/pipelined/src/lsu/lsu.sv @@ -91,7 +91,7 @@ module lsu ( logic [2:0] LSUFunct3M; logic [6:0] LSUFunct7M; logic [1:0] LSUAtomicM; - (* mark_debug = "true" *) logic [`PA_BITS-1:0] PreLSUPAdrM; + (* mark_debug = "true" *) logic [`XLEN+1:0] PreLSUPAdrM; logic [11:0] PreLSUAdrE, LSUAdrE; logic CPUBusy; logic DCacheStallM; @@ -132,7 +132,7 @@ module lsu ( assign {InterlockStall, SelHPTW, PTE, PageType, DTLBWriteM, ITLBWriteF, IgnoreRequestTLB} = '0; assign IgnoreRequestTrapM = TrapM; assign CPUBusy = StallW; assign PreLSURWM = MemRWM; assign LSUAdrE = PreLSUAdrE; assign PreLSUAdrE = IEUAdrE[11:0]; - assign PreLSUPAdrM = IEUAdrExtM[`PA_BITS-1:0]; + assign PreLSUPAdrM = IEUAdrExtM; assign LSUFunct3M = Funct3M; assign LSUFunct7M = Funct7M; assign LSUAtomicM = AtomicM; assign LSUWriteDataM = WriteDataM; end @@ -151,8 +151,7 @@ module lsu ( mmu #(.TLB_ENTRIES(`DTLB_ENTRIES), .IMMU(0)) dmmu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .PrivilegeModeW, .DisableTranslation, - .PAdr(PreLSUPAdrM), - .VAdr(IEUAdrM), + .VAdr(PreLSUPAdrM), .Size(LSUFunct3M[1:0]), .PTE, .PageTypeWriteVal(PageType), diff --git a/pipelined/src/lsu/lsuvirtmen.sv b/pipelined/src/lsu/lsuvirtmen.sv index 83176470e..751c2c928 100644 --- a/pipelined/src/lsu/lsuvirtmen.sv +++ b/pipelined/src/lsu/lsuvirtmen.sv @@ -59,7 +59,7 @@ module lsuvirtmem( output logic [1:0] PreLSURWM, output logic [1:0] LSUAtomicM, output logic [11:0] LSUAdrE, - output logic [`PA_BITS-1:0] PreLSUPAdrM, + output logic [`XLEN+1:0] PreLSUPAdrM, input logic [`XLEN+1:0] IEUAdrExtM, // *** can move internally. output logic InterlockStall, @@ -71,13 +71,15 @@ module lsuvirtmem( logic AnyCPUReqM; logic [`PA_BITS-1:0] HPTWAdr; + logic [`XLEN+1:0] HPTWAdrExt; logic [1:0] HPTWRW; logic [2:0] HPTWSize; logic SelReplayMemE; logic [11:0] PreLSUAdrE; logic ITLBMissOrDAFaultF, ITLBMissOrDAFaultNoTrapF; - logic DTLBMissOrDAFaultM, DTLBMissOrDAFaultNoTrapM; - + logic DTLBMissOrDAFaultM, DTLBMissOrDAFaultNoTrapM; + logic SelHPTWAdr; + assign ITLBMissOrDAFaultF = ITLBMissF | (`HPTW_WRITES_SUPPORTED & InstrDAPageFaultF); assign DTLBMissOrDAFaultM = DTLBMissM | (`HPTW_WRITES_SUPPORTED & DataDAPageFaultM); assign ITLBMissOrDAFaultNoTrapF = ITLBMissOrDAFaultF & ~TrapM; @@ -94,13 +96,22 @@ module lsuvirtmem( .DCacheStallM, .HPTWAdr, .HPTWRW, .HPTWSize); // *** possible future optimization of simplifying page table entry with precomputed misalignment (Ross) low priority + // Once the walk is done and it is time to update the DTLB we need to switch back + // to the orignal data virtual address. + assign SelHPTWAdr = SelHPTW & ~DTLBWriteM; + // multiplex the outputs to LSU + if(`XLEN+2-`PA_BITS > 0) begin + logic [(`XLEN+2-`PA_BITS)-1:0] zeros; + assign zeros = '0; + assign HPTWAdrExt = {zeros, HPTWAdr}; + end else assign HPTWAdrExt = HPTWAdr; mux2 #(2) rwmux(MemRWM, HPTWRW, SelHPTW, PreLSURWM); mux2 #(3) sizemux(Funct3M, HPTWSize, SelHPTW, LSUFunct3M); mux2 #(7) funct7mux(Funct7M, 7'b0, SelHPTW, LSUFunct7M); mux2 #(2) atomicmux(AtomicM, 2'b00, SelHPTW, LSUAtomicM); mux2 #(12) adremux(IEUAdrE[11:0], HPTWAdr[11:0], SelHPTW, PreLSUAdrE); - mux2 #(`PA_BITS) lsupadrmux(IEUAdrExtM[`PA_BITS-1:0], HPTWAdr, SelHPTW, PreLSUPAdrM); + mux2 #(`XLEN+2) lsupadrmux(IEUAdrExtM, HPTWAdrExt, SelHPTWAdr, PreLSUPAdrM); if(`HPTW_WRITES_SUPPORTED) mux2 #(`XLEN) lsuwritedatamux(WriteDataM, PTE, SelHPTW, LSUWriteDataM); else assign LSUWriteDataM = WriteDataM; diff --git a/pipelined/src/mmu/mmu.sv b/pipelined/src/mmu/mmu.sv index 0d53aaccd..ccf49ce48 100644 --- a/pipelined/src/mmu/mmu.sv +++ b/pipelined/src/mmu/mmu.sv @@ -49,16 +49,10 @@ module mmu #(parameter TLB_ENTRIES = 8, // number of TLB Entries // 11 - TLB is accessed for both read and write input logic DisableTranslation, - // VAdr goes to the TLB only. Virtual if the TLB is active. - // PAdr goes to address mux bypassing the TLB. PAdr used when there is no translation. - // Comes from either the program address (instruction address or load/store address) - // or from the hardware pagetable walker. - // PAdr is intended to used as a phsycial address. Discarded by the address mux when translation is - // performed. + // VAdr is the virtual/physical address from IEU or physical address from HPTW. // PhysicalAddress is selected to be PAdr when no translation or the translated VAdr (TLBPAdr) // when there is translation. - input logic [`PA_BITS-1:0] PAdr, // *** consider renaming this. - input logic [`XLEN-1:0] VAdr, + input logic [`XLEN+1:0] VAdr, input logic [1:0] Size, // 00 = 8 bits, 01 = 16 bits, 10 = 32 bits , 11 = 64 bits // Controls for writing a new entry to the TLB @@ -106,7 +100,7 @@ module mmu #(parameter TLB_ENTRIES = 8, // number of TLB Entries tlb(.clk, .reset, .SATP_MODE(SATP_REGW[`XLEN-1:`XLEN-`SVMODE_BITS]), .SATP_ASID(SATP_REGW[`ASID_BASE+`ASID_BITS-1:`ASID_BASE]), - .VAdr, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, + .VAdr(VAdr[`XLEN-1:0]), .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .PrivilegeModeW, .ReadAccess, .WriteAccess, .DisableTranslation, .PTE, .PageTypeWriteVal, .TLBWrite, .TLBFlush, .TLBPAdr, .TLBMiss, .TLBHit, @@ -122,8 +116,8 @@ module mmu #(parameter TLB_ENTRIES = 8, // number of TLB Entries // the lower 12 bits are the page offset. These are never changed from the orginal // non translated address. //mux2 #(`PA_BITS) addressmux(PAdr, TLBPAdr, Translate, PhysicalAddress); - mux2 #(`PA_BITS-12) addressmux(PAdr[`PA_BITS-1:12], TLBPAdr[`PA_BITS-1:12], Translate, PhysicalAddress[`PA_BITS-1:12]); - assign PhysicalAddress[11:0] = PAdr[11:0]; + mux2 #(`PA_BITS-12) addressmux(VAdr[`PA_BITS-1:12], TLBPAdr[`PA_BITS-1:12], Translate, PhysicalAddress[`PA_BITS-1:12]); + assign PhysicalAddress[11:0] = VAdr[11:0]; /////////////////////////////////////////// From 5f88536730d93aa2754f549c5e480cfe00362945 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Mon, 28 Mar 2022 10:23:20 -0500 Subject: [PATCH 03/18] Temporary change of plic uart id to 10. --- pipelined/config/fpga/wally-config.vh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipelined/config/fpga/wally-config.vh b/pipelined/config/fpga/wally-config.vh index 2e8063e23..a1dc805b3 100644 --- a/pipelined/config/fpga/wally-config.vh +++ b/pipelined/config/fpga/wally-config.vh @@ -123,7 +123,7 @@ // Interrupt configuration `define PLIC_NUM_SRC 53 -`define PLIC_UART_ID 4 +`define PLIC_UART_ID 10 `define TWO_BIT_PRELOAD "../config/fpga/twoBitPredictor.txt" `define BTB_PRELOAD "../config/fpga/BTBPredictor.txt" From 09ff5c2c451aaa542c07d962f9a811bf8939ec93 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Mon, 28 Mar 2022 10:52:26 -0500 Subject: [PATCH 04/18] Updated debug2.xdc ila constraints to match rtl. --- fpga/constraints/debug2.xdc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fpga/constraints/debug2.xdc b/fpga/constraints/debug2.xdc index 9c3e5a5f6..4ace8b682 100644 --- a/fpga/constraints/debug2.xdc +++ b/fpga/constraints/debug2.xdc @@ -41,7 +41,7 @@ connect_debug_port u_ila_0/probe5 [get_nets [list {wallypipelinedsoc/core/ReadDa create_debug_port u_ila_0 probe set_property port_width 64 [get_debug_ports u_ila_0/probe6] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe6] -connect_debug_port u_ila_0/probe6 [get_nets [list {wallypipelinedsoc/core/WriteDataM[0]} {wallypipelinedsoc/core/WriteDataM[1]} {wallypipelinedsoc/core/WriteDataM[2]} {wallypipelinedsoc/core/WriteDataM[3]} {wallypipelinedsoc/core/WriteDataM[4]} {wallypipelinedsoc/core/WriteDataM[5]} {wallypipelinedsoc/core/WriteDataM[6]} {wallypipelinedsoc/core/WriteDataM[7]} {wallypipelinedsoc/core/WriteDataM[8]} {wallypipelinedsoc/core/WriteDataM[9]} {wallypipelinedsoc/core/WriteDataM[10]} {wallypipelinedsoc/core/WriteDataM[11]} {wallypipelinedsoc/core/WriteDataM[12]} {wallypipelinedsoc/core/WriteDataM[13]} {wallypipelinedsoc/core/WriteDataM[14]} {wallypipelinedsoc/core/WriteDataM[15]} {wallypipelinedsoc/core/WriteDataM[16]} {wallypipelinedsoc/core/WriteDataM[17]} {wallypipelinedsoc/core/WriteDataM[18]} {wallypipelinedsoc/core/WriteDataM[19]} {wallypipelinedsoc/core/WriteDataM[20]} {wallypipelinedsoc/core/WriteDataM[21]} {wallypipelinedsoc/core/WriteDataM[22]} {wallypipelinedsoc/core/WriteDataM[23]} {wallypipelinedsoc/core/WriteDataM[24]} {wallypipelinedsoc/core/WriteDataM[25]} {wallypipelinedsoc/core/WriteDataM[26]} {wallypipelinedsoc/core/WriteDataM[27]} {wallypipelinedsoc/core/WriteDataM[28]} {wallypipelinedsoc/core/WriteDataM[29]} {wallypipelinedsoc/core/WriteDataM[30]} {wallypipelinedsoc/core/WriteDataM[31]} {wallypipelinedsoc/core/WriteDataM[32]} {wallypipelinedsoc/core/WriteDataM[33]} {wallypipelinedsoc/core/WriteDataM[34]} {wallypipelinedsoc/core/WriteDataM[35]} {wallypipelinedsoc/core/WriteDataM[36]} {wallypipelinedsoc/core/WriteDataM[37]} {wallypipelinedsoc/core/WriteDataM[38]} {wallypipelinedsoc/core/WriteDataM[39]} {wallypipelinedsoc/core/WriteDataM[40]} {wallypipelinedsoc/core/WriteDataM[41]} {wallypipelinedsoc/core/WriteDataM[42]} {wallypipelinedsoc/core/WriteDataM[43]} {wallypipelinedsoc/core/WriteDataM[44]} {wallypipelinedsoc/core/WriteDataM[45]} {wallypipelinedsoc/core/WriteDataM[46]} {wallypipelinedsoc/core/WriteDataM[47]} {wallypipelinedsoc/core/WriteDataM[48]} {wallypipelinedsoc/core/WriteDataM[49]} {wallypipelinedsoc/core/WriteDataM[50]} {wallypipelinedsoc/core/WriteDataM[51]} {wallypipelinedsoc/core/WriteDataM[52]} {wallypipelinedsoc/core/WriteDataM[53]} {wallypipelinedsoc/core/WriteDataM[54]} {wallypipelinedsoc/core/WriteDataM[55]} {wallypipelinedsoc/core/WriteDataM[56]} {wallypipelinedsoc/core/WriteDataM[57]} {wallypipelinedsoc/core/WriteDataM[58]} {wallypipelinedsoc/core/WriteDataM[59]} {wallypipelinedsoc/core/WriteDataM[60]} {wallypipelinedsoc/core/WriteDataM[61]} {wallypipelinedsoc/core/WriteDataM[62]} {wallypipelinedsoc/core/WriteDataM[63]} ]] +connect_debug_port u_ila_0/probe6 [get_nets [list {wallypipelinedsoc/core/lsu/WriteDataM[0]} {wallypipelinedsoc/core/lsu/WriteDataM[1]} {wallypipelinedsoc/core/lsu/WriteDataM[2]} {wallypipelinedsoc/core/lsu/WriteDataM[3]} {wallypipelinedsoc/core/lsu/WriteDataM[4]} {wallypipelinedsoc/core/lsu/WriteDataM[5]} {wallypipelinedsoc/core/lsu/WriteDataM[6]} {wallypipelinedsoc/core/lsu/WriteDataM[7]} {wallypipelinedsoc/core/lsu/WriteDataM[8]} {wallypipelinedsoc/core/lsu/WriteDataM[9]} {wallypipelinedsoc/core/lsu/WriteDataM[10]} {wallypipelinedsoc/core/lsu/WriteDataM[11]} {wallypipelinedsoc/core/lsu/WriteDataM[12]} {wallypipelinedsoc/core/lsu/WriteDataM[13]} {wallypipelinedsoc/core/lsu/WriteDataM[14]} {wallypipelinedsoc/core/lsu/WriteDataM[15]} {wallypipelinedsoc/core/lsu/WriteDataM[16]} {wallypipelinedsoc/core/lsu/WriteDataM[17]} {wallypipelinedsoc/core/lsu/WriteDataM[18]} {wallypipelinedsoc/core/lsu/WriteDataM[19]} {wallypipelinedsoc/core/lsu/WriteDataM[20]} {wallypipelinedsoc/core/lsu/WriteDataM[21]} {wallypipelinedsoc/core/lsu/WriteDataM[22]} {wallypipelinedsoc/core/lsu/WriteDataM[23]} {wallypipelinedsoc/core/lsu/WriteDataM[24]} {wallypipelinedsoc/core/lsu/WriteDataM[25]} {wallypipelinedsoc/core/lsu/WriteDataM[26]} {wallypipelinedsoc/core/lsu/WriteDataM[27]} {wallypipelinedsoc/core/lsu/WriteDataM[28]} {wallypipelinedsoc/core/lsu/WriteDataM[29]} {wallypipelinedsoc/core/lsu/WriteDataM[30]} {wallypipelinedsoc/core/lsu/WriteDataM[31]} {wallypipelinedsoc/core/lsu/WriteDataM[32]} {wallypipelinedsoc/core/lsu/WriteDataM[33]} {wallypipelinedsoc/core/lsu/WriteDataM[34]} {wallypipelinedsoc/core/lsu/WriteDataM[35]} {wallypipelinedsoc/core/lsu/WriteDataM[36]} {wallypipelinedsoc/core/lsu/WriteDataM[37]} {wallypipelinedsoc/core/lsu/WriteDataM[38]} {wallypipelinedsoc/core/lsu/WriteDataM[39]} {wallypipelinedsoc/core/lsu/WriteDataM[40]} {wallypipelinedsoc/core/lsu/WriteDataM[41]} {wallypipelinedsoc/core/lsu/WriteDataM[42]} {wallypipelinedsoc/core/lsu/WriteDataM[43]} {wallypipelinedsoc/core/lsu/WriteDataM[44]} {wallypipelinedsoc/core/lsu/WriteDataM[45]} {wallypipelinedsoc/core/lsu/WriteDataM[46]} {wallypipelinedsoc/core/lsu/WriteDataM[47]} {wallypipelinedsoc/core/lsu/WriteDataM[48]} {wallypipelinedsoc/core/lsu/WriteDataM[49]} {wallypipelinedsoc/core/lsu/WriteDataM[50]} {wallypipelinedsoc/core/lsu/WriteDataM[51]} {wallypipelinedsoc/core/lsu/WriteDataM[52]} {wallypipelinedsoc/core/lsu/WriteDataM[53]} {wallypipelinedsoc/core/lsu/WriteDataM[54]} {wallypipelinedsoc/core/lsu/WriteDataM[55]} {wallypipelinedsoc/core/lsu/WriteDataM[56]} {wallypipelinedsoc/core/lsu/WriteDataM[57]} {wallypipelinedsoc/core/lsu/WriteDataM[58]} {wallypipelinedsoc/core/lsu/WriteDataM[59]} {wallypipelinedsoc/core/lsu/WriteDataM[60]} {wallypipelinedsoc/core/lsu/WriteDataM[61]} {wallypipelinedsoc/core/lsu/WriteDataM[62]} {wallypipelinedsoc/core/lsu/WriteDataM[63]} ]] create_debug_port u_ila_0 probe set_property port_width 64 [get_debug_ports u_ila_0/probe7] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe7] @@ -155,6 +155,7 @@ create_debug_port u_ila_0 probe set_property port_width 1 [get_debug_ports u_ila_0/probe34] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe34] connect_debug_port u_ila_0/probe34 [get_nets [list wallypipelinedsoc/core/lsu/LSUBusWrite ]] + create_debug_port u_ila_0 probe set_property port_width 1 [get_debug_ports u_ila_0/probe35] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe35] @@ -195,10 +196,12 @@ create_debug_port u_ila_0 probe set_property port_width 1 [get_debug_ports u_ila_0/probe44] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe44] connect_debug_port u_ila_0/probe44 [get_nets [list wallypipelinedsoc/core/priv.priv/trap/InstrPageFaultM ]] + create_debug_port u_ila_0 probe set_property port_width 1 [get_debug_ports u_ila_0/probe45] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe45] connect_debug_port u_ila_0/probe45 [get_nets [list wallypipelinedsoc/core/InstrValidM ]] + create_debug_port u_ila_0 probe set_property port_width 1 [get_debug_ports u_ila_0/probe46] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe46] From c88541cf6bbc2c51cb0145698ab25e68055f2fba Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Mon, 28 Mar 2022 17:04:58 -0500 Subject: [PATCH 05/18] test. --- fpga/generator/wally.tcl | 3 ++ pipelined/src/uncore/ram.sv | 84 ++++++++++++++++++------------------- 2 files changed, 45 insertions(+), 42 deletions(-) diff --git a/fpga/generator/wally.tcl b/fpga/generator/wally.tcl index 824574d9c..60666077a 100644 --- a/fpga/generator/wally.tcl +++ b/fpga/generator/wally.tcl @@ -52,6 +52,9 @@ report_utilization -hierarchical -file re report_cdc -file reports/cdc.rpt report_clock_interaction -file reports/clock_interaction.rpt +write_verilog -force -mode funcsim sim/syn-funcsim.v + + source ../constraints/debug2.xdc diff --git a/pipelined/src/uncore/ram.sv b/pipelined/src/uncore/ram.sv index e9b0af32d..61dec5a5c 100644 --- a/pipelined/src/uncore/ram.sv +++ b/pipelined/src/uncore/ram.sv @@ -60,48 +60,48 @@ module ram #(parameter BASE=0, RANGE = 65535) ( // *** need to address this preload for fpga. It should work as a preload file // but for some reason vivado is not synthesizing the preload. //$readmemh(PRELOAD, RAM); - RAM[0] = 64'h94e1819300002197; - RAM[1] = 64'h4281420141014081; - RAM[2] = 64'h4481440143814301; - RAM[3] = 64'h4681460145814501; - RAM[4] = 64'h4881480147814701; - RAM[5] = 64'h4a814a0149814901; - RAM[6] = 64'h4c814c014b814b01; - RAM[7] = 64'h4e814e014d814d01; - RAM[8] = 64'h0110011b4f814f01; - RAM[9] = 64'h059b45011161016e; - RAM[10] = 64'h0004063705fe0010; - RAM[11] = 64'h05a000ef8006061b; - RAM[12] = 64'h0ff003930000100f; - RAM[13] = 64'h4e952e3110060e37; - RAM[14] = 64'hc602829b0053f2b7; - RAM[15] = 64'h2023fe02dfe312fd; - RAM[16] = 64'h829b0053f2b7007e; - RAM[17] = 64'hfe02dfe312fdc602; - RAM[18] = 64'h4de31efd000e2023; - RAM[19] = 64'h059bf1402573fdd0; - RAM[20] = 64'h0000061705e20870; - RAM[21] = 64'h0010029b01260613; - RAM[22] = 64'h11010002806702fe; - RAM[23] = 64'h84b2842ae426e822; - RAM[24] = 64'h892ee04aec064505; - RAM[25] = 64'h06e000ef07e000ef; - RAM[26] = 64'h979334fd02905563; - RAM[27] = 64'h07930177d4930204; - RAM[28] = 64'h4089093394be2004; - RAM[29] = 64'h04138522008905b3; - RAM[30] = 64'h19e3014000ef2004; - RAM[31] = 64'h64a2644260e2fe94; - RAM[32] = 64'h6749808261056902; - RAM[33] = 64'hdfed8b8510472783; - RAM[34] = 64'h2423479110a73823; - RAM[35] = 64'h10472783674910f7; - RAM[36] = 64'h20058693ffed8b89; - RAM[37] = 64'h05a1118737836749; - RAM[38] = 64'hfed59be3fef5bc23; - RAM[39] = 64'h1047278367498082; - RAM[40] = 64'h67c98082dfed8b85; - RAM[41] = 64'h0000808210a7a023; + RAM[BASE+0] = 64'h94e1819300002197; + RAM[BASE+1] = 64'h4281420141014081; + RAM[BASE+2] = 64'h4481440143814301; + RAM[BASE+3] = 64'h4681460145814501; + RAM[BASE+4] = 64'h4881480147814701; + RAM[BASE+5] = 64'h4a814a0149814901; + RAM[BASE+6] = 64'h4c814c014b814b01; + RAM[BASE+7] = 64'h4e814e014d814d01; + RAM[BASE+8] = 64'h0110011b4f814f01; + RAM[BASE+9] = 64'h059b45011161016e; + RAM[BASE+10] = 64'h0004063705fe0010; + RAM[BASE+11] = 64'h05a000ef8006061b; + RAM[BASE+12] = 64'h0ff003930000100f; + RAM[BASE+13] = 64'h4e952e3110060e37; + RAM[BASE+14] = 64'hc602829b0053f2b7; + RAM[BASE+15] = 64'h2023fe02dfe312fd; + RAM[BASE+16] = 64'h829b0053f2b7007e; + RAM[BASE+17] = 64'hfe02dfe312fdc602; + RAM[BASE+18] = 64'h4de31efd000e2023; + RAM[BASE+19] = 64'h059bf1402573fdd0; + RAM[BASE+20] = 64'h0000061705e20870; + RAM[BASE+21] = 64'h0010029b01260613; + RAM[BASE+22] = 64'h11010002806702fe; + RAM[BASE+23] = 64'h84b2842ae426e822; + RAM[BASE+24] = 64'h892ee04aec064505; + RAM[BASE+25] = 64'h06e000ef07e000ef; + RAM[BASE+26] = 64'h979334fd02905563; + RAM[BASE+27] = 64'h07930177d4930204; + RAM[BASE+28] = 64'h4089093394be2004; + RAM[BASE+29] = 64'h04138522008905b3; + RAM[BASE+30] = 64'h19e3014000ef2004; + RAM[BASE+31] = 64'h64a2644260e2fe94; + RAM[BASE+32] = 64'h6749808261056902; + RAM[BASE+33] = 64'hdfed8b8510472783; + RAM[BASE+34] = 64'h2423479110a73823; + RAM[BASE+35] = 64'h10472783674910f7; + RAM[BASE+36] = 64'h20058693ffed8b89; + RAM[BASE+37] = 64'h05a1118737836749; + RAM[BASE+38] = 64'hfed59be3fef5bc23; + RAM[BASE+39] = 64'h1047278367498082; + RAM[BASE+40] = 64'h67c98082dfed8b85; + RAM[BASE+41] = 64'h0000808210a7a023; end // initial begin end // if (FPGA) From 03fa9084bc06bd1f367e5ee80d07baf68ede1c3a Mon Sep 17 00:00:00 2001 From: David Harris Date: Tue, 29 Mar 2022 19:16:41 +0000 Subject: [PATCH 06/18] Updated synthesis to look at fma16.v, other scripts to use fma16.v instead of fma16.sv --- pipelined/src/fma/fma.do | 2 +- pipelined/src/fma/lint-fma | 2 +- synthDC/scripts/synth.tcl | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/pipelined/src/fma/fma.do b/pipelined/src/fma/fma.do index 9a7de1267..6e6863d5f 100644 --- a/pipelined/src/fma/fma.do +++ b/pipelined/src/fma/fma.do @@ -8,7 +8,7 @@ onbreak {resume} # create library vlib worklib -vlog -lint -work worklib fma16.sv testbench.v +vlog -lint -work worklib fma16.v testbench.v vopt +acc worklib.testbench_fma16 -work worklib -o testbenchopt vsim -lib worklib testbenchopt diff --git a/pipelined/src/fma/lint-fma b/pipelined/src/fma/lint-fma index 462d53508..290bf69ff 100755 --- a/pipelined/src/fma/lint-fma +++ b/pipelined/src/fma/lint-fma @@ -5,4 +5,4 @@ export PATH=$PATH:/usr/local/bin/ verilator=`which verilator` basepath=$(dirname $0)/.. -$verilator --lint-only --top-module fma16 fma16.sv +$verilator --lint-only --top-module fma16 fma16.v diff --git a/synthDC/scripts/synth.tcl b/synthDC/scripts/synth.tcl index 3146e14ed..d79009fe1 100755 --- a/synthDC/scripts/synth.tcl +++ b/synthDC/scripts/synth.tcl @@ -28,6 +28,9 @@ eval file copy -force [glob ${hdl_src}/../config/shared/*.vh] {hdl/} eval file copy -force [glob ${hdl_src}/*/*.sv] {hdl/} eval file copy -force [glob ${hdl_src}/*/flop/*.sv] {hdl/} +# Only for FMA class project; comment out when done +eval file copy -force [glob ${hdl_src}/fma/fma16.v] {hdl/} + # Enables name mapping if { $saifpower == 1 } { saif_map -start From 66e9380cfbeac8bcc54f8552dbef5a78f45049c9 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 29 Mar 2022 19:12:29 -0500 Subject: [PATCH 07/18] Partial fix to allow byte write enables with fpga and still get a preload to work. --- pipelined/src/generic/flop/bram.sv | 47 +++++++++++++ pipelined/src/uncore/ram.sv | 2 +- pipelined/src/uncore/ram3.sv | 105 +++++++++++++++++++++++++++++ pipelined/testbench/testbench.sv | 24 +++---- 4 files changed, 165 insertions(+), 13 deletions(-) create mode 100644 pipelined/src/generic/flop/bram.sv create mode 100644 pipelined/src/uncore/ram3.sv diff --git a/pipelined/src/generic/flop/bram.sv b/pipelined/src/generic/flop/bram.sv new file mode 100644 index 000000000..75fb76635 --- /dev/null +++ b/pipelined/src/generic/flop/bram.sv @@ -0,0 +1,47 @@ +// This model actually works correctly with vivado. + + +module bram2p1r1w + #( + //-------------------------------------------------------------------------- + parameter NUM_COL = 8, + parameter COL_WIDTH = 8, + parameter ADDR_WIDTH = 10, + // Addr Width in bits : 2 *ADDR_WIDTH = RAM Depth + parameter DATA_WIDTH = NUM_COL*COL_WIDTH // Data Width in bits + //---------------------------------------------------------------------- + ) ( + input logic clk, + input logic enaA, + input logic [ADDR_WIDTH-1:0] addrA, + output logic [DATA_WIDTH-1:0] doutA, + input logic enaB, + input logic [NUM_COL-1:0] weB, + input logic [ADDR_WIDTH-1:0] addrB, + input logic [DATA_WIDTH-1:0] dinB + ); + // Core Memory + logic [DATA_WIDTH-1:0] RAM [(2**ADDR_WIDTH)-1:0]; + integer i; + + initial begin + $readmemh("big64.txt", RAM); + end + + // Port-A Operation + always @ (posedge clk) begin + if(enaA) begin + doutA <= RAM[addrA]; + end + end + // Port-B Operation: + always @ (posedge clk) begin + if(enaB) begin + for(i=0;i Date: Tue, 29 Mar 2022 23:48:19 -0500 Subject: [PATCH 08/18] rv32gc and rv64gc now use the updated ram3.sv (will rename to ram.sv) which uses a vivado block ram compatible memory. Still need to update simpleram.sv to use this block ram compatible memory. --- pipelined/src/uncore/ram3.sv | 7 ++++--- pipelined/testbench/testbench-linux.sv | 10 +++++----- pipelined/testbench/testbench.sv | 18 ++++++++++-------- 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/pipelined/src/uncore/ram3.sv b/pipelined/src/uncore/ram3.sv index ad568b70c..90a3196ba 100644 --- a/pipelined/src/uncore/ram3.sv +++ b/pipelined/src/uncore/ram3.sv @@ -56,7 +56,7 @@ module ram #(parameter BASE=0, RANGE = 65535) ( logic memwrite; logic [3:0] busycount; - swbytemask swbytemask(.HSIZED, .HADDRD(A[2:0]), .ByteMask(ByteMaskM)); + swbytemask swbytemask(.HSIZED, .HADDRD(HWADDR[2:0]), .ByteMask(ByteMaskM)); assign initTrans = HREADY & HSELRam & (HTRANS != 2'b00); @@ -83,6 +83,7 @@ module ram #(parameter BASE=0, RANGE = 65535) ( assign HRESPRam = 0; // OK localparam ADDR_WDITH = $clog2(RANGE/8); + localparam OFFSET = $clog2(`XLEN/8); // Rising HREADY edge detector // Indicates when ram is finishing up @@ -96,9 +97,9 @@ module ram #(parameter BASE=0, RANGE = 65535) ( bram2p1r1w #(`XLEN/8, 8, ADDR_WDITH) memory(.clk(HCLK), .enaA(1'b1), - .addrA(A[ADDR_WDITH+2:3]), .doutA(HREADRam), + .addrA(A[ADDR_WDITH+OFFSET-1:OFFSET]), .doutA(HREADRam), .enaB(memwrite & risingHREADYRam), .weB(ByteMaskM), - .addrB(HWADDR[ADDR_WDITH+2:3]), .dinB(HWDATA)); + .addrB(HWADDR[ADDR_WDITH+OFFSET-1:OFFSET]), .dinB(HWDATA)); endmodule diff --git a/pipelined/testbench/testbench-linux.sv b/pipelined/testbench/testbench-linux.sv index 6044d124d..dfaa70e61 100644 --- a/pipelined/testbench/testbench-linux.sv +++ b/pipelined/testbench/testbench-linux.sv @@ -353,21 +353,21 @@ module testbench; ProgramLabelMapFile = {linuxImageDir,"disassembly/vmlinux.objdump.lab"}; // initialize bootrom memFile = $fopen({testvectorDir,"bootmem.bin"}, "rb"); - readResult = $fread(dut.uncore.bootrom.bootrom.RAM,memFile); + readResult = $fread(dut.uncore.bootrom.bootrom.memory.RAM,memFile); $fclose(memFile); // initialize RAM if (CHECKPOINT==0) memFile = $fopen({testvectorDir,"ram.bin"}, "rb"); else memFile = $fopen({checkpointDir,"ram.bin"}, "rb"); - readResult = $fread(dut.uncore.ram.ram.RAM,memFile); + readResult = $fread(dut.uncore.ram.ram.memory.RAM,memFile); $fclose(memFile); if (CHECKPOINT==0) begin // normal traceFileM = $fopen({testvectorDir,"all.txt"}, "r"); traceFileE = $fopen({testvectorDir,"all.txt"}, "r"); InstrCountW = '0; end else begin // checkpoint - //$readmemh({checkpointDir,"ram.txt"}, dut.uncore.ram.ram.RAM); + //$readmemh({checkpointDir,"ram.txt"}, dut.uncore.ram.ram.memory.RAM); traceFileE = $fopen({checkpointDir,"all.txt"}, "r"); traceFileM = $fopen({checkpointDir,"all.txt"}, "r"); InstrCountW = CHECKPOINT; @@ -771,9 +771,9 @@ module testbench; BaseAdr = SATP[43:0] << 12; for (i = 2; i >= 0; i--) begin PAdr = BaseAdr + (VPN[i] << 3); - // ram.RAM is 64-bit addressed. PAdr specifies a byte. We right shift + // ram.memory.RAM is 64-bit addressed. PAdr specifies a byte. We right shift // by 3 (the PTE size) to get the requested 64-bit PTE. - PTE = dut.uncore.ram.ram.RAM[PAdr >> 3]; + PTE = dut.uncore.ram.ram.memory.RAM[PAdr >> 3]; PTE_R = PTE[1]; PTE_X = PTE[3]; if (PTE_R | PTE_X) begin diff --git a/pipelined/testbench/testbench.sv b/pipelined/testbench/testbench.sv index 9bb2ed029..105493399 100644 --- a/pipelined/testbench/testbench.sv +++ b/pipelined/testbench/testbench.sv @@ -44,7 +44,7 @@ module testbench; int test, i, errors, totalerrors; logic [31:0] sig32[0:SIGNATURESIZE]; logic [`XLEN-1:0] signature[0:SIGNATURESIZE]; - logic [`XLEN-1:0] testadr; + logic [`XLEN-1:0] testadr, testadrNoBase; string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName; logic [31:0] InstrW; @@ -170,6 +170,7 @@ logic [3:0] dummy; test = 1; totalerrors = 0; testadr = 0; + testadrNoBase = 0; // fill memory with defined values to reduce Xs in simulation // Quick note the memory will need to be initialized. The C library does not // guarantee the initialized reads. For example a strcmp can read 6 byte @@ -186,9 +187,9 @@ logic [3:0] dummy; pathname = tvpaths[0]; else pathname = tvpaths[1]; */ memfilename = {pathname, tests[test], ".elf.memfile"}; - if (`IMEM == `MEM_TIM) $readmemh(memfilename, dut.core.ifu.irom.irom.ram.memory.RAM); + if (`IMEM == `MEM_TIM) $readmemh(memfilename, dut.core.ifu.irom.irom.ram.RAM); else $readmemh(memfilename, dut.uncore.ram.ram.memory.RAM); - if (`DMEM == `MEM_TIM) $readmemh(memfilename, dut.core.lsu.dtim.dtim.ram.memory.RAM); + if (`DMEM == `MEM_TIM) $readmemh(memfilename, dut.core.lsu.dtim.dtim.ram.RAM); ProgramAddrMapFile = {pathname, tests[test], ".elf.objdump.addr"}; ProgramLabelMapFile = {pathname, tests[test], ".elf.objdump.lab"}; @@ -243,12 +244,13 @@ logic [3:0] dummy; errors = (i == SIGNATURESIZE+1); // error if file is empty i = 0; testadr = (`RAM_BASE+tests[test+1].atohex())/(`XLEN/8); + testadrNoBase = (tests[test+1].atohex())/(`XLEN/8); /* verilator lint_off INFINITELOOP */ while (signature[i] !== 'bx) begin logic [`XLEN-1:0] sig; - if (`DMEM == `MEM_TIM) sig = dut.core.lsu.dtim.dtim.ram.memory.RAM[testadr+i]; - else sig = dut.uncore.ram.ram.memory.RAM[testadr+i]; -// $display("signature[%h] = %h sig = %h", i, signature[i], sig); + if (`DMEM == `MEM_TIM) sig = dut.core.lsu.dtim.dtim.ram.RAM[testadr+i]; + else sig = dut.uncore.ram.ram.memory.RAM[testadrNoBase+i]; + //$display("signature[%h] = %h sig = %h", i, signature[i], sig); if (signature[i] !== sig & //if (signature[i] !== dut.core.lsu.dtim.ram.memory.RAM[testadr+i] & (signature[i] !== DCacheFlushFSM.ShadowRAM[testadr+i])) begin // ***i+1? @@ -284,9 +286,9 @@ logic [3:0] dummy; //pathname = tvpaths[tests[0]]; memfilename = {pathname, tests[test], ".elf.memfile"}; //$readmemh(memfilename, dut.uncore.ram.ram.memory.RAM); - if (`IMEM == `MEM_TIM) $readmemh(memfilename, dut.core.ifu.irom.irom.ram.memory.RAM); + if (`IMEM == `MEM_TIM) $readmemh(memfilename, dut.core.ifu.irom.irom.ram.RAM); else $readmemh(memfilename, dut.uncore.ram.ram.memory.RAM); - if (`DMEM == `MEM_TIM) $readmemh(memfilename, dut.core.lsu.dtim.dtim.ram.memory.RAM); + if (`DMEM == `MEM_TIM) $readmemh(memfilename, dut.core.lsu.dtim.dtim.ram.RAM); ProgramAddrMapFile = {pathname, tests[test], ".elf.objdump.addr"}; ProgramLabelMapFile = {pathname, tests[test], ".elf.objdump.lab"}; From 839bede65676582f857f1e6a68877932d0e36760 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Wed, 30 Mar 2022 11:04:15 -0500 Subject: [PATCH 09/18] Converted over to the blockram/sram memories. Now I just need to cleanup. But before the cleanup I wan to make sure the FPGA synthesizes with these changes and actually keeps the preload. --- pipelined/src/generic/flop/bram.sv | 47 ------------------------- pipelined/src/generic/flop/simpleram.sv | 9 +++++ pipelined/src/lsu/dtim.sv | 2 +- pipelined/testbench/testbench.sv | 10 +++--- 4 files changed, 15 insertions(+), 53 deletions(-) delete mode 100644 pipelined/src/generic/flop/bram.sv diff --git a/pipelined/src/generic/flop/bram.sv b/pipelined/src/generic/flop/bram.sv deleted file mode 100644 index 75fb76635..000000000 --- a/pipelined/src/generic/flop/bram.sv +++ /dev/null @@ -1,47 +0,0 @@ -// This model actually works correctly with vivado. - - -module bram2p1r1w - #( - //-------------------------------------------------------------------------- - parameter NUM_COL = 8, - parameter COL_WIDTH = 8, - parameter ADDR_WIDTH = 10, - // Addr Width in bits : 2 *ADDR_WIDTH = RAM Depth - parameter DATA_WIDTH = NUM_COL*COL_WIDTH // Data Width in bits - //---------------------------------------------------------------------- - ) ( - input logic clk, - input logic enaA, - input logic [ADDR_WIDTH-1:0] addrA, - output logic [DATA_WIDTH-1:0] doutA, - input logic enaB, - input logic [NUM_COL-1:0] weB, - input logic [ADDR_WIDTH-1:0] addrB, - input logic [DATA_WIDTH-1:0] dinB - ); - // Core Memory - logic [DATA_WIDTH-1:0] RAM [(2**ADDR_WIDTH)-1:0]; - integer i; - - initial begin - $readmemh("big64.txt", RAM); - end - - // Port-A Operation - always @ (posedge clk) begin - if(enaA) begin - doutA <= RAM[addrA]; - end - end - // Port-B Operation: - always @ (posedge clk) begin - if(enaB) begin - for(i=0;i>(1+`XLEN/32):(RANGE+BASE)>>1+(`XLEN/32)]; // discard bottom 2 or 3 bits of address offset within word or doubleword @@ -55,5 +63,6 @@ module simpleram #(parameter BASE=0, RANGE = 65535) ( if (we & ByteMask[index]) RAM[adrmsbs][8*(index+1)-1:8*index] <= #1 wd[8*(index+1)-1:8*index]; end end + -----/\----- EXCLUDED -----/\----- */ endmodule diff --git a/pipelined/src/lsu/dtim.sv b/pipelined/src/lsu/dtim.sv index 6ca5be4a6..5b4969ab8 100644 --- a/pipelined/src/lsu/dtim.sv +++ b/pipelined/src/lsu/dtim.sv @@ -48,7 +48,7 @@ module dtim( output logic DCacheCommittedM, output logic DCacheMiss, output logic DCacheAccess); - + simpleram #(.BASE(`RAM_BASE), .RANGE(`RAM_RANGE)) ram ( .clk, .ByteMask(ByteMaskM), .a(CPUBusy | LSURWM[0] | reset ? IEUAdrM[31:0] : IEUAdrE[31:0]), // move mux out; this shouldn't be needed when stails are handled differently *** diff --git a/pipelined/testbench/testbench.sv b/pipelined/testbench/testbench.sv index 105493399..2b8e6df8b 100644 --- a/pipelined/testbench/testbench.sv +++ b/pipelined/testbench/testbench.sv @@ -187,9 +187,9 @@ logic [3:0] dummy; pathname = tvpaths[0]; else pathname = tvpaths[1]; */ memfilename = {pathname, tests[test], ".elf.memfile"}; - if (`IMEM == `MEM_TIM) $readmemh(memfilename, dut.core.ifu.irom.irom.ram.RAM); + if (`IMEM == `MEM_TIM) $readmemh(memfilename, dut.core.ifu.irom.irom.ram.memory.RAM); else $readmemh(memfilename, dut.uncore.ram.ram.memory.RAM); - if (`DMEM == `MEM_TIM) $readmemh(memfilename, dut.core.lsu.dtim.dtim.ram.RAM); + if (`DMEM == `MEM_TIM) $readmemh(memfilename, dut.core.lsu.dtim.dtim.ram.memory.RAM); ProgramAddrMapFile = {pathname, tests[test], ".elf.objdump.addr"}; ProgramLabelMapFile = {pathname, tests[test], ".elf.objdump.lab"}; @@ -248,7 +248,7 @@ logic [3:0] dummy; /* verilator lint_off INFINITELOOP */ while (signature[i] !== 'bx) begin logic [`XLEN-1:0] sig; - if (`DMEM == `MEM_TIM) sig = dut.core.lsu.dtim.dtim.ram.RAM[testadr+i]; + if (`DMEM == `MEM_TIM) sig = dut.core.lsu.dtim.dtim.ram.memory.RAM[testadrNoBase+i]; else sig = dut.uncore.ram.ram.memory.RAM[testadrNoBase+i]; //$display("signature[%h] = %h sig = %h", i, signature[i], sig); if (signature[i] !== sig & @@ -286,9 +286,9 @@ logic [3:0] dummy; //pathname = tvpaths[tests[0]]; memfilename = {pathname, tests[test], ".elf.memfile"}; //$readmemh(memfilename, dut.uncore.ram.ram.memory.RAM); - if (`IMEM == `MEM_TIM) $readmemh(memfilename, dut.core.ifu.irom.irom.ram.RAM); + if (`IMEM == `MEM_TIM) $readmemh(memfilename, dut.core.ifu.irom.irom.ram.memory.RAM); else $readmemh(memfilename, dut.uncore.ram.ram.memory.RAM); - if (`DMEM == `MEM_TIM) $readmemh(memfilename, dut.core.lsu.dtim.dtim.ram.RAM); + if (`DMEM == `MEM_TIM) $readmemh(memfilename, dut.core.lsu.dtim.dtim.ram.memory.RAM); ProgramAddrMapFile = {pathname, tests[test], ".elf.objdump.addr"}; ProgramLabelMapFile = {pathname, tests[test], ".elf.objdump.lab"}; From f52ab0136299480c936123541d2828b0d8cdf171 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Wed, 30 Mar 2022 11:09:21 -0500 Subject: [PATCH 10/18] Partial cleanup of memories. --- pipelined/src/generic/flop/bram1p1rw.sv | 71 +++++++++++++ pipelined/src/generic/flop/bram2p1r1w.sv | 82 +++++++++++++++ pipelined/src/uncore/ram.sv | 121 +++++------------------ pipelined/src/uncore/ram3.sv | 106 -------------------- 4 files changed, 175 insertions(+), 205 deletions(-) create mode 100644 pipelined/src/generic/flop/bram1p1rw.sv create mode 100644 pipelined/src/generic/flop/bram2p1r1w.sv delete mode 100644 pipelined/src/uncore/ram3.sv diff --git a/pipelined/src/generic/flop/bram1p1rw.sv b/pipelined/src/generic/flop/bram1p1rw.sv new file mode 100644 index 000000000..2b17fb447 --- /dev/null +++ b/pipelined/src/generic/flop/bram1p1rw.sv @@ -0,0 +1,71 @@ +/////////////////////////////////////////// +// block ram model should be equivalent to srsam. +// +// Written: Ross Thompson +// March 29, 2022 +// Modified: Based on UG901 vivado documentation. +// +// Purpose: On-chip SIMPLERAM, external to core +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// MIT LICENSE +// 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. +//////////////////////////////////////////////////////////////////////////////////////////////// + +// This model actually works correctly with vivado. + +`include "wally-config.vh" + +module bram1p1rw + #( + //-------------------------------------------------------------------------- + parameter NUM_COL = 8, + parameter COL_WIDTH = 8, + parameter ADDR_WIDTH = 10, + // Addr Width in bits : 2 *ADDR_WIDTH = RAM Depth + parameter DATA_WIDTH = NUM_COL*COL_WIDTH // Data Width in bits + //---------------------------------------------------------------------- + ) ( + input logic clk, + input logic ena, + input logic [NUM_COL-1:0] we, + input logic [ADDR_WIDTH-1:0] addr, + output logic [DATA_WIDTH-1:0] dout, + input logic [DATA_WIDTH-1:0] din + ); + // Core Memory + logic [DATA_WIDTH-1:0] RAM [(2**ADDR_WIDTH)-1:0]; + integer i; + + initial begin + $readmemh("big64.txt", RAM); + end + + always @ (posedge clk) begin + dout <= RAM[addr]; + if(ena) begin + for(i=0;i>(1+`XLEN/32); - localparam MemEndAddr = (RANGE+BASE)>>1+(`XLEN/32); + logic [`XLEN/8-1:0] ByteMaskM; + logic [31:0] HWADDR, A; + logic prevHREADYRam, risingHREADYRam; + logic initTrans; + logic memwrite; + logic [3:0] busycount; - logic [`XLEN-1:0] RAM[BASE>>(1+`XLEN/32):(RANGE+BASE)>>1+(`XLEN/32)]; - logic [31:0] HWADDR, A; + swbytemask swbytemask(.HSIZED, .HADDRD(HWADDR[2:0]), .ByteMask(ByteMaskM)); - logic prevHREADYRam, risingHREADYRam; - logic initTrans; - logic memwrite; - logic [3:0] busycount; - logic [`XLEN/8-1:0] ByteMaskM; - - if(`FPGA) begin:ram - initial begin - // *** need to address this preload for fpga. It should work as a preload file - // but for some reason vivado is not synthesizing the preload. - //$readmemh(PRELOAD, RAM); - RAM[0] = 64'h94e1819300002197; - RAM[1] = 64'h4281420141014081; - RAM[2] = 64'h4481440143814301; - RAM[3] = 64'h4681460145814501; - RAM[4] = 64'h4881480147814701; - RAM[5] = 64'h4a814a0149814901; - RAM[6] = 64'h4c814c014b814b01; - RAM[7] = 64'h4e814e014d814d01; - RAM[8] = 64'h0110011b4f814f01; - RAM[9] = 64'h059b45011161016e; - RAM[10] = 64'h0004063705fe0010; - RAM[11] = 64'h05a000ef8006061b; - RAM[12] = 64'h0ff003930000100f; - RAM[13] = 64'h4e952e3110060e37; - RAM[14] = 64'hc602829b0053f2b7; - RAM[15] = 64'h2023fe02dfe312fd; - RAM[16] = 64'h829b0053f2b7007e; - RAM[17] = 64'hfe02dfe312fdc602; - RAM[18] = 64'h4de31efd000e2023; - RAM[19] = 64'h059bf1402573fdd0; - RAM[20] = 64'h0000061705e20870; - RAM[21] = 64'h0010029b01260613; - RAM[22] = 64'h11010002806702fe; - RAM[23] = 64'h84b2842ae426e822; - RAM[24] = 64'h892ee04aec064505; - RAM[25] = 64'h06e000ef07e000ef; - RAM[26] = 64'h979334fd02905563; - RAM[27] = 64'h07930177d4930204; - RAM[28] = 64'h4089093394be2004; - RAM[29] = 64'h04138522008905b3; - RAM[30] = 64'h19e3014000ef2004; - RAM[31] = 64'h64a2644260e2fe94; - RAM[32] = 64'h6749808261056902; - RAM[33] = 64'hdfed8b8510472783; - RAM[34] = 64'h2423479110a73823; - RAM[35] = 64'h10472783674910f7; - RAM[36] = 64'h20058693ffed8b89; - RAM[37] = 64'h05a1118737836749; - RAM[38] = 64'hfed59be3fef5bc23; - RAM[39] = 64'h1047278367498082; - RAM[40] = 64'h67c98082dfed8b85; - RAM[41] = 64'h0000808210a7a023; - end // initial begin - end // if (FPGA) - - swbytemask swbytemask(.HSIZED, .HADDRD(A[2:0]), .ByteMask(ByteMaskM)); - assign initTrans = HREADY & HSELRam & (HTRANS != 2'b00); // *** this seems like a weird way to use reset flopenr #(1) memwritereg(HCLK, 1'b0, initTrans | ~HRESETn, HSELRam & HWRITE, memwrite); flopenr #(32) haddrreg(HCLK, 1'b0, initTrans | ~HRESETn, HADDR, A); - // busy FSM to extend READY signal - always_ff @(posedge HCLK, negedge HRESETn) + always @(posedge HCLK, negedge HRESETn) if (~HRESETn) begin busycount <= 0; HREADYRam <= #1 0; @@ -131,47 +75,26 @@ module ramOld #(parameter BASE=0, RANGE = 65535) ( end end assign HRESPRam = 0; // OK + + localparam ADDR_WDITH = $clog2(RANGE/8); + localparam OFFSET = $clog2(`XLEN/8); // Rising HREADY edge detector // Indicates when ram is finishing up // Needed because HREADY may go high for other reasons, // and we only want to write data when finishing up. - flopr #(1) prevhreadyRamreg(HCLK,~HRESETn,HREADYRam,prevHREADYRam); + flopenr #(1) prevhreadyRamreg(HCLK,~HRESETn, 1'b1, HREADYRam,prevHREADYRam); assign risingHREADYRam = HREADYRam & ~prevHREADYRam; - // Model memory read and write -/* -----\/----- EXCLUDED -----\/----- - integer index; - - initial begin - for(index = MemStartAddr; index < MemEndAddr; index = index + 1) begin - RAM[index] <= {`XLEN{1'b0}}; - end - end - -----/\----- EXCLUDED -----/\----- */ - - /* verilator lint_off WIDTH */ - genvar index; - always_ff @(posedge HCLK) + always @(posedge HCLK) HWADDR <= #1 A; - if (`XLEN == 64) begin:ramrw - always_ff @(posedge HCLK) - HREADRam <= #1 RAM[A[31:3]]; - for(index = 0; index < `XLEN/8; index++) begin - always_ff @(posedge HCLK) begin - if (memwrite & risingHREADYRam & ByteMaskM[index]) RAM[HWADDR[31:3]][8*(index+1)-1:8*index] <= #1 HWDATA[8*(index+1)-1:8*index]; - end - end - end else begin - always_ff @(posedge HCLK) - HREADRam <= #1 RAM[A[31:2]]; - for(index = 0; index < `XLEN/8; index++) begin - always_ff @(posedge HCLK) begin:ramrw - if (memwrite & risingHREADYRam & ByteMaskM[index]) RAM[HWADDR[31:2]][8*(index+1)-1:8*index] <= #1 HWDATA[8*(index+1)-1:8*index]; - end - end - end - /* verilator lint_on WIDTH */ + bram2p1r1w #(`XLEN/8, 8, ADDR_WDITH, `FPGA) + memory(.clk(HCLK), .enaA(1'b1), + .addrA(A[ADDR_WDITH+OFFSET-1:OFFSET]), .doutA(HREADRam), + .enaB(memwrite & risingHREADYRam), .weB(ByteMaskM), + .addrB(HWADDR[ADDR_WDITH+OFFSET-1:OFFSET]), .dinB(HWDATA)); + + endmodule - + diff --git a/pipelined/src/uncore/ram3.sv b/pipelined/src/uncore/ram3.sv deleted file mode 100644 index 90a3196ba..000000000 --- a/pipelined/src/uncore/ram3.sv +++ /dev/null @@ -1,106 +0,0 @@ -/////////////////////////////////////////// -// ram.sv -// -// Written: David_Harris@hmc.edu 9 January 2021 -// Modified: -// -// Purpose: On-chip RAM, external to core -// -// A component of the Wally configurable RISC-V project. -// -// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University -// -// MIT LICENSE -// 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. -//////////////////////////////////////////////////////////////////////////////////////////////// - -// True-Dual-Port BRAM with Byte-wide Write Enable -// Read-First mode -// bytewrite_tdp_ram_rf.v -// - -`include "wally-config.vh" - - -module ram #(parameter BASE=0, RANGE = 65535) ( - input logic HCLK, HRESETn, - input logic HSELRam, - input logic [31:0] HADDR, - input logic HWRITE, - input logic HREADY, - input logic [1:0] HTRANS, - input logic [`XLEN-1:0] HWDATA, - input logic [3:0] HSIZED, - output logic [`XLEN-1:0] HREADRam, - output logic HRESPRam, HREADYRam -); - - logic [`XLEN/8-1:0] ByteMaskM; - logic [31:0] HWADDR, A; - logic prevHREADYRam, risingHREADYRam; - logic initTrans; - logic memwrite; - logic [3:0] busycount; - - swbytemask swbytemask(.HSIZED, .HADDRD(HWADDR[2:0]), .ByteMask(ByteMaskM)); - - assign initTrans = HREADY & HSELRam & (HTRANS != 2'b00); - - // *** this seems like a weird way to use reset - flopenr #(1) memwritereg(HCLK, 1'b0, initTrans | ~HRESETn, HSELRam & HWRITE, memwrite); - flopenr #(32) haddrreg(HCLK, 1'b0, initTrans | ~HRESETn, HADDR, A); - // busy FSM to extend READY signal - always @(posedge HCLK, negedge HRESETn) - if (~HRESETn) begin - busycount <= 0; - HREADYRam <= #1 0; - end else begin - if (initTrans) begin - busycount <= 0; - HREADYRam <= #1 0; - end else if (~HREADYRam) begin - if (busycount == 0) begin // Ram latency, for testing purposes. *** test with different values such as 2 - HREADYRam <= #1 1; - end else begin - busycount <= busycount + 1; - end - end - end - assign HRESPRam = 0; // OK - - localparam ADDR_WDITH = $clog2(RANGE/8); - localparam OFFSET = $clog2(`XLEN/8); - - // Rising HREADY edge detector - // Indicates when ram is finishing up - // Needed because HREADY may go high for other reasons, - // and we only want to write data when finishing up. - flopenr #(1) prevhreadyRamreg(HCLK,~HRESETn, 1'b1, HREADYRam,prevHREADYRam); - assign risingHREADYRam = HREADYRam & ~prevHREADYRam; - - always @(posedge HCLK) - HWADDR <= #1 A; - - bram2p1r1w #(`XLEN/8, 8, ADDR_WDITH) - memory(.clk(HCLK), .enaA(1'b1), - .addrA(A[ADDR_WDITH+OFFSET-1:OFFSET]), .doutA(HREADRam), - .enaB(memwrite & risingHREADYRam), .weB(ByteMaskM), - .addrB(HWADDR[ADDR_WDITH+OFFSET-1:OFFSET]), .dinB(HWDATA)); - - -endmodule - From 0a5b500aca7a69c6d6b6bb9bd6dcfb31d015cd24 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Wed, 30 Mar 2022 11:38:25 -0500 Subject: [PATCH 11/18] Changed sram1p1rw to have the same type of bytewrite enables as bram. --- pipelined/src/cache/sram1p1rw.sv | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/pipelined/src/cache/sram1p1rw.sv b/pipelined/src/cache/sram1p1rw.sv index 5ecb7374a..94ec7ce80 100644 --- a/pipelined/src/cache/sram1p1rw.sv +++ b/pipelined/src/cache/sram1p1rw.sv @@ -47,7 +47,8 @@ module sram1p1rw #(parameter DEPTH=128, WIDTH=256) ( always_ff @(posedge clk) AdrD <= Adr; - genvar index; + integer index; +/* -----\/----- EXCLUDED -----\/----- for(index = 0; index < WIDTH/8; index++) begin always_ff @(posedge clk) begin if (WriteEnable & ByteMask[index]) begin @@ -55,6 +56,18 @@ module sram1p1rw #(parameter DEPTH=128, WIDTH=256) ( end end end + -----/\----- EXCLUDED -----/\----- */ + + always_ff @(posedge clk) begin + if (WriteEnable) begin + for(index = 0; index < WIDTH/8; index++) begin + if(ByteMask[index]) begin + StoredData[Adr][index*8 +: 8] <= #1 CacheWriteData[index*8 +: 8]; + end + end + end + end + // if not a multiple of 8, MSByte is not 8 bits long. if(WIDTH%8 != 0) begin always_ff @(posedge clk) begin From 69a0f6e00b0c5575a92ee2ee2424ed6701afd012 Mon Sep 17 00:00:00 2001 From: bbracker Date: Wed, 30 Mar 2022 13:22:41 -0700 Subject: [PATCH 12/18] big interrupts refactor --- pipelined/src/ifu/ifu.sv | 2 +- pipelined/src/privileged/csr.sv | 13 ++-- pipelined/src/privileged/csri.sv | 68 ++++++++----------- pipelined/src/privileged/csrm.sv | 79 ++++++++++++----------- pipelined/src/privileged/privileged.sv | 17 +++-- pipelined/src/privileged/trap.sv | 29 +++++---- pipelined/src/uncore/plic.sv | 12 ++-- pipelined/src/uncore/uncore.sv | 8 +-- pipelined/src/wally/wallypipelinedcore.sv | 9 ++- pipelined/src/wally/wallypipelinedsoc.sv | 6 +- pipelined/testbench/testbench-linux.sv | 2 +- 11 files changed, 116 insertions(+), 129 deletions(-) diff --git a/pipelined/src/ifu/ifu.sv b/pipelined/src/ifu/ifu.sv index 480556aaa..0e8c2f79f 100644 --- a/pipelined/src/ifu/ifu.sv +++ b/pipelined/src/ifu/ifu.sv @@ -66,7 +66,7 @@ module ifu ( output logic IllegalIEUInstrFaultD, output logic InstrMisalignedFaultM, output logic [`XLEN-1:0] InstrMisalignedAdrM, - input logic ExceptionM, PendingInterruptM, + input logic ExceptionM, // mmu management input logic [1:0] PrivilegeModeW, input logic [`XLEN-1:0] PTE, diff --git a/pipelined/src/privileged/csr.sv b/pipelined/src/privileged/csr.sv index ecdcbe50d..489ee9539 100644 --- a/pipelined/src/privileged/csr.sv +++ b/pipelined/src/privileged/csr.sv @@ -43,7 +43,7 @@ module csr #(parameter input logic [31:0] InstrM, input logic [`XLEN-1:0] PCM, SrcAM, input logic CSRReadM, CSRWriteM, TrapM, MTrapM, STrapM, UTrapM, mretM, sretM, - input logic TimerIntM, ExtIntM, ExtIntS, SwIntM, + input logic TimerIntM, MExtIntM, SExtIntM, SwIntM, input logic [63:0] MTIME_CLINT, input logic InstrValidM, FRegWriteM, LoadStallD, input logic BPPredDirWrongM, @@ -60,9 +60,9 @@ module csr #(parameter output logic [1:0] STATUS_MPP, output logic STATUS_SPP, STATUS_TSR, output logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW, STVEC_REGW, MTVEC_REGW, - output logic [`XLEN-1:0] MEDELEG_REGW, MIDELEG_REGW, + output logic [`XLEN-1:0] MEDELEG_REGW, output logic [`XLEN-1:0] SATP_REGW, - output logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW, + output logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW, MIDELEG_REGW, output logic STATUS_MIE, STATUS_SIE, output logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, STATUS_TW, output var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], @@ -122,9 +122,10 @@ module csr #(parameter assign CSRSWriteM = CSRWriteM & (|PrivilegeModeW); assign CSRUWriteM = CSRWriteM; - csri csri(.clk, .reset, .InstrValidNotFlushedM, .StallW, .CSRMWriteM, .CSRSWriteM, - .CSRAdrM, .ExtIntM, .ExtIntS, .TimerIntM, .SwIntM, - .MIDELEG_REGW, .MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, .CSRWriteValM); + csri csri(.clk, .reset, .InstrValidNotFlushedM, .StallW, + .CSRMWriteM, .CSRSWriteM, .CSRWriteValM, .CSRAdrM, + .MExtIntM, .SExtIntM, .TimerIntM, .SwIntM, + .MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, .MIDELEG_REGW); csrsr csrsr(.clk, .reset, .StallW, .WriteMSTATUSM, .WriteSSTATUSM, .TrapM, .FRegWriteM, .NextPrivilegeModeM, .PrivilegeModeW, diff --git a/pipelined/src/privileged/csri.sv b/pipelined/src/privileged/csri.sv index 16d084f8d..68a265b55 100644 --- a/pipelined/src/privileged/csri.sv +++ b/pipelined/src/privileged/csri.sv @@ -32,78 +32,62 @@ `include "wally-config.vh" module csri #(parameter - // Machine CSRs - MIE = 12'h304, - MIP = 12'h344, - SIE = 12'h104, - SIP = 12'h144) ( + MIE = 12'h304, + MIP = 12'h344, + SIE = 12'h104, + SIP = 12'h144 + ) ( input logic clk, reset, input logic InstrValidNotFlushedM, StallW, input logic CSRMWriteM, CSRSWriteM, + input logic [`XLEN-1:0] CSRWriteValM, input logic [11:0] CSRAdrM, - input logic ExtIntM, ExtIntS, TimerIntM, SwIntM, - input logic [`XLEN-1:0] MIDELEG_REGW, - output logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW, - input logic [`XLEN-1:0] CSRWriteValM + input logic MExtIntM, SExtIntM, TimerIntM, SwIntM, + input logic [11:0] MIDELEG_REGW, + output logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW ); - logic [9:0] IP_REGW_writeable; - logic [11:0] IntInM, IP_REGW, IE_REGW; - logic [11:0] MIP_WRITE_MASK, SIP_WRITE_MASK; + logic [11:0] IP_REGW_writeable; // only SEIP, STIP, SSIP are actually writeable; the rest are hardwired to 0 + logic [11:0] IP_REGW, IE_REGW; + logic [11:0] MIP_WRITE_MASK, SIP_WRITE_MASK, MIE_WRITE_MASK; logic WriteMIPM, WriteMIEM, WriteSIPM, WriteSIEM; - // Determine which interrupts need to be set - // assumes no N-mode user interrupts - - always_comb begin - IntInM = 0; - IntInM[11] = ExtIntM; // MEIP - IntInM[9] = (ExtIntM & MIDELEG_REGW[9]); // SEIP - IntInM[7] = TimerIntM; // MTIP - IntInM[5] = TimerIntM & MIDELEG_REGW[5]; // STIP - IntInM[3] = SwIntM; // MSIP - IntInM[1] = SwIntM & MIDELEG_REGW[1]; // SSIP - end - // Interrupt Write Enables assign WriteMIPM = CSRMWriteM & (CSRAdrM == MIP) & InstrValidNotFlushedM; assign WriteMIEM = CSRMWriteM & (CSRAdrM == MIE) & InstrValidNotFlushedM; assign WriteSIPM = CSRSWriteM & (CSRAdrM == SIP) & InstrValidNotFlushedM; assign WriteSIEM = CSRSWriteM & (CSRAdrM == SIE) & InstrValidNotFlushedM; -// Interrupt Pending and Enable Registers -// MEIP, MTIP, MSIP are read-only -// SEIP, STIP, SSIP is writable in MIP if S mode exists -// SSIP is writable in SIP if S mode exists + // Interrupt Pending and Enable Registers + // MEIP, MTIP, MSIP are read-only + // SEIP, STIP, SSIP is writable in MIP if S mode exists + // SSIP is writable in SIP if S mode exists if (`S_SUPPORTED) begin:mask assign MIP_WRITE_MASK = 12'h222; // SEIP, STIP, SSIP are writable in MIP (20210108-draft 3.1.9) assign SIP_WRITE_MASK = 12'h002; // SSIP is writable in SIP (privileged 20210108-draft 4.1.3) + assign MIE_WRITE_MASK = 12'hAAA; end else begin:mask assign MIP_WRITE_MASK = 12'h000; assign SIP_WRITE_MASK = 12'h000; + assign MIE_WRITE_MASK = 12'h888; end always @(posedge clk) - if (reset) IP_REGW_writeable <= 10'b0; - else if (WriteMIPM) IP_REGW_writeable <= (CSRWriteValM[9:0] & MIP_WRITE_MASK[9:0]) | {1'b0,IntInM[8:0]}; // MTIP unclearable - else if (WriteSIPM) IP_REGW_writeable <= (CSRWriteValM[9:0] & SIP_WRITE_MASK[9:0]) | {1'b0,IntInM[8:0]}; // MTIP unclearable - else IP_REGW_writeable <= IP_REGW_writeable | {1'b0, IntInM[8:0]}; // *** check this turns off interrupts properly even when MIDELEG changes + if (reset) IP_REGW_writeable <= 12'b0; + else if (WriteMIPM) IP_REGW_writeable <= (CSRWriteValM[11:0] & MIP_WRITE_MASK); + else if (WriteSIPM) IP_REGW_writeable <= (CSRWriteValM[11:0] & SIP_WRITE_MASK); always @(posedge clk) if (reset) IE_REGW <= 12'b0; - else if (WriteMIEM) IE_REGW <= (CSRWriteValM[11:0] & 12'hAAA); // MIE controls M and S fields + else if (WriteMIEM) IE_REGW <= (CSRWriteValM[11:0] & MIE_WRITE_MASK); // MIE controls M and S fields else if (WriteSIEM) IE_REGW <= (CSRWriteValM[11:0] & 12'h222) | (IE_REGW & 12'h888); // only S fields - // restricted views of registers - // Add ExtIntM read-only signal - assign IP_REGW = {ExtIntM,1'b0,ExtIntS,1'b0, IntInM[7], 7'b0} | {2'b0, IP_REGW_writeable[9], 3'b0, IP_REGW_writeable[5], 3'b0, IP_REGW_writeable[1], 1'b0}; // *** This is just to force the Machine level bits of IP to be unwriteable and to only come from intInM. PLEASE CHANGE ME!!! - - // Machine Mode + assign IP_REGW = {MExtIntM,1'b0,SExtIntM|IP_REGW_writeable[9],1'b0,TimerIntM,1'b0,IP_REGW_writeable[5],1'b0,SwIntM,1'b0,IP_REGW_writeable[1],1'b0}; + assign MIP_REGW = IP_REGW; assign MIE_REGW = IE_REGW; - // Supervisor mode if (`S_SUPPORTED) begin - assign SIP_REGW = IP_REGW & MIDELEG_REGW[11:0] & 'h222; // only delegated interrupts visible - assign SIE_REGW = IE_REGW & MIDELEG_REGW[11:0] & 'h222; + assign SIP_REGW = IP_REGW & 12'h222; + assign SIE_REGW = IE_REGW & 12'h222; end else begin assign SIP_REGW = 12'b0; assign SIE_REGW = 12'b0; diff --git a/pipelined/src/privileged/csrm.sv b/pipelined/src/privileged/csrm.sv index c66d2d38a..8315d38f0 100644 --- a/pipelined/src/privileged/csrm.sv +++ b/pipelined/src/privileged/csrm.sv @@ -33,42 +33,42 @@ `include "wally-config.vh" module csrm #(parameter - // Machine CSRs - MVENDORID = 12'hF11, - MARCHID = 12'hF12, - MIMPID = 12'hF13, - MHARTID = 12'hF14, - MSTATUS = 12'h300, - MISA_ADR = 12'h301, - MEDELEG = 12'h302, - MIDELEG = 12'h303, - MIE = 12'h304, - MTVEC = 12'h305, - MCOUNTEREN = 12'h306, - MSTATUSH = 12'h310, - MCOUNTINHIBIT = 12'h320, - MSCRATCH = 12'h340, - MEPC = 12'h341, - MCAUSE = 12'h342, - MTVAL = 12'h343, - MIP = 12'h344, - PMPCFG0 = 12'h3A0, - // .. up to 15 more at consecutive addresses - PMPADDR0 = 12'h3B0, - // ... up to 63 more at consecutive addresses - TSELECT = 12'h7A0, - TDATA1 = 12'h7A1, - TDATA2 = 12'h7A2, - TDATA3 = 12'h7A3, - DCSR = 12'h7B0, - DPC = 12'h7B1, - DSCRATCH0 = 12'h7B2, - DSCRATCH1 = 12'h7B3, - // Constants - ZERO = {(`XLEN){1'b0}}, - MEDELEG_MASK = ~(ZERO | `XLEN'b1 << 11), - MIDELEG_MASK = {{(`XLEN-12){1'b0}}, 12'h222} -) ( + // Machine CSRs + MVENDORID = 12'hF11, + MARCHID = 12'hF12, + MIMPID = 12'hF13, + MHARTID = 12'hF14, + MSTATUS = 12'h300, + MISA_ADR = 12'h301, + MEDELEG = 12'h302, + MIDELEG = 12'h303, + MIE = 12'h304, + MTVEC = 12'h305, + MCOUNTEREN = 12'h306, + MSTATUSH = 12'h310, + MCOUNTINHIBIT = 12'h320, + MSCRATCH = 12'h340, + MEPC = 12'h341, + MCAUSE = 12'h342, + MTVAL = 12'h343, + MIP = 12'h344, + PMPCFG0 = 12'h3A0, + // .. up to 15 more at consecutive addresses + PMPADDR0 = 12'h3B0, + // ... up to 63 more at consecutive addresses + TSELECT = 12'h7A0, + TDATA1 = 12'h7A1, + TDATA2 = 12'h7A2, + TDATA3 = 12'h7A3, + DCSR = 12'h7B0, + DPC = 12'h7B1, + DSCRATCH0 = 12'h7B2, + DSCRATCH1 = 12'h7B3, + // Constants + ZERO = {(`XLEN){1'b0}}, + MEDELEG_MASK = ~(ZERO | `XLEN'b1 << 11), + MIDELEG_MASK = 12'h222 // we choose to not make machine interrupts delegable + ) ( input logic clk, reset, input logic InstrValidNotFlushedM, StallW, input logic CSRMWriteM, MTrapM, @@ -78,7 +78,8 @@ module csrm #(parameter output logic [`XLEN-1:0] CSRMReadValM, MTVEC_REGW, (* mark_debug = "true" *) output logic [`XLEN-1:0] MEPC_REGW, output logic [31:0] MCOUNTEREN_REGW, MCOUNTINHIBIT_REGW, - output logic [`XLEN-1:0] MEDELEG_REGW, MIDELEG_REGW, + output logic [`XLEN-1:0] MEDELEG_REGW, + output logic [11:0] MIDELEG_REGW, // 64-bit registers in RV64, or two 32-bit registers in RV32 //output var logic [63:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES/8-1:0], output var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], @@ -148,7 +149,7 @@ module csrm #(parameter flopenr #(`XLEN) MTVECreg(clk, reset, WriteMTVECM, {CSRWriteValM[`XLEN-1:2], 1'b0, CSRWriteValM[0]}, MTVEC_REGW); if (`S_SUPPORTED) begin:deleg // DELEG registers should exist flopenr #(`XLEN) MEDELEGreg(clk, reset, WriteMEDELEGM, CSRWriteValM & MEDELEG_MASK /*12'h7FF*/, MEDELEG_REGW); - flopenr #(`XLEN) MIDELEGreg(clk, reset, WriteMIDELEGM, CSRWriteValM & MIDELEG_MASK /*12'h222*/, MIDELEG_REGW); + flopenr #(12) MIDELEGreg(clk, reset, WriteMIDELEGM, CSRWriteValM[11:0] & MIDELEG_MASK /*12'h222*/, MIDELEG_REGW); end else assign {MEDELEG_REGW, MIDELEG_REGW} = 0; flopenr #(`XLEN) MSCRATCHreg(clk, reset, WriteMSCRATCHM, CSRWriteValM, MSCRATCH_REGW); @@ -188,7 +189,7 @@ module csrm #(parameter MSTATUSH: CSRMReadValM = 0; // flush this out later if MBE and SBE fields are supported MTVEC: CSRMReadValM = MTVEC_REGW; MEDELEG: CSRMReadValM = MEDELEG_REGW; - MIDELEG: CSRMReadValM = MIDELEG_REGW; + MIDELEG: CSRMReadValM = {{(`XLEN-12){1'b0}}, MIDELEG_REGW}; MIP: CSRMReadValM = {{(`XLEN-12){1'b0}}, MIP_REGW}; MIE: CSRMReadValM = {{(`XLEN-12){1'b0}}, MIE_REGW}; MSCRATCH: CSRMReadValM = MSCRATCH_REGW; diff --git a/pipelined/src/privileged/privileged.sv b/pipelined/src/privileged/privileged.sv index 9a8fb9f8a..4f056662b 100644 --- a/pipelined/src/privileged/privileged.sv +++ b/pipelined/src/privileged/privileged.sv @@ -55,7 +55,7 @@ module privileged ( input logic InstrMisalignedFaultM, IllegalIEUInstrFaultD, IllegalFPUInstrD, input logic LoadMisalignedFaultM, input logic StoreAmoMisalignedFaultM, - input logic TimerIntM, ExtIntM, ExtIntS, SwIntM, + input logic TimerIntM, MExtIntM, SExtIntM, SwIntM, input logic [63:0] MTIME_CLINT, input logic [`XLEN-1:0] InstrMisalignedAdrM, IEUAdrM, input logic [4:0] SetFflagsM, @@ -69,7 +69,6 @@ module privileged ( input logic StoreAmoAccessFaultM, output logic ExceptionM, - output logic PendingInterruptM, output logic IllegalFPUInstrE, output logic [1:0] PrivilegeModeW, output logic [`XLEN-1:0] SATP_REGW, @@ -86,7 +85,8 @@ module privileged ( logic [`XLEN-1:0] CauseM, NextFaultMtvalM; logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW, STVEC_REGW, MTVEC_REGW; - logic [`XLEN-1:0] MEDELEG_REGW, MIDELEG_REGW; + logic [`XLEN-1:0] MEDELEG_REGW; + logic [11:0] MIDELEG_REGW; logic sretM, mretM, ecallM, ebreakM, wfiM, sfencevmaM; logic IllegalCSRAccessM; @@ -111,7 +111,7 @@ module privileged ( /////////////////////////////////////////// // get bits of DELEG registers based on CAUSE - assign md = CauseM[`XLEN-1] ? MIDELEG_REGW[CauseM[`LOG_XLEN-1:0]] : MEDELEG_REGW[CauseM[`LOG_XLEN-1:0]]; + assign md = CauseM[`XLEN-1] ? MIDELEG_REGW[CauseM[3:0]] : MEDELEG_REGW[CauseM[`LOG_XLEN-1:0]]; // PrivilegeMode FSM always_comb begin @@ -150,7 +150,7 @@ module privileged ( .StallE, .StallM, .StallW, .InstrM, .PCM, .SrcAM, .CSRReadM, .CSRWriteM, .TrapM, .MTrapM, .STrapM, .UTrapM, .mretM, .sretM, - .TimerIntM, .ExtIntM, .ExtIntS, .SwIntM, + .TimerIntM, .MExtIntM, .SExtIntM, .SwIntM, .MTIME_CLINT, .InstrValidM, .FRegWriteM, .LoadStallD, .BPPredDirWrongM, .BTBPredPCWrongM, .RASPredPCWrongM, @@ -159,9 +159,9 @@ module privileged ( .CauseM, .NextFaultMtvalM, .STATUS_MPP, .STATUS_SPP, .STATUS_TSR, .MEPC_REGW, .SEPC_REGW, .STVEC_REGW, .MTVEC_REGW, - .MEDELEG_REGW, .MIDELEG_REGW, + .MEDELEG_REGW, .SATP_REGW, - .MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, + .MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, .MIDELEG_REGW, .STATUS_MIE, .STATUS_SIE, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_TW, .PMPCFG_ARRAY_REGW, @@ -210,7 +210,7 @@ module privileged ( .mretM, .sretM, .PrivilegeModeW, .NextPrivilegeModeM, .MEPC_REGW, .SEPC_REGW, .STVEC_REGW, .MTVEC_REGW, - .MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, + .MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, .MIDELEG_REGW, .STATUS_MIE, .STATUS_SIE, .PCM, .InstrMisalignedAdrM, .IEUAdrM, @@ -219,7 +219,6 @@ module privileged ( .TrapM, .MTrapM, .STrapM, .UTrapM, .RetM, .InterruptM, .ExceptionM, - .PendingInterruptM, .PrivilegedNextPCM, .CauseM, .NextFaultMtvalM); endmodule diff --git a/pipelined/src/privileged/trap.sv b/pipelined/src/privileged/trap.sv index 7f61a5a71..25a246a5a 100644 --- a/pipelined/src/privileged/trap.sv +++ b/pipelined/src/privileged/trap.sv @@ -41,7 +41,7 @@ module trap ( (* mark_debug = "true" *) input logic mretM, sretM, input logic [1:0] PrivilegeModeW, NextPrivilegeModeM, (* mark_debug = "true" *) input logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW, STVEC_REGW, MTVEC_REGW, - (* mark_debug = "true" *) input logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW, + (* mark_debug = "true" *) input logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW, MIDELEG_REGW, input logic STATUS_MIE, STATUS_SIE, input logic [`XLEN-1:0] PCM, input logic [`XLEN-1:0] InstrMisalignedAdrM, IEUAdrM, @@ -50,15 +50,13 @@ module trap ( output logic TrapM, MTrapM, STrapM, UTrapM, RetM, output logic InterruptM, output logic ExceptionM, - output logic PendingInterruptM, - output logic [`XLEN-1:0] PrivilegedNextPCM, CauseM, NextFaultMtvalM // output logic [11:0] MIP_REGW, SIP_REGW, UIP_REGW, MIE_REGW, SIE_REGW, UIE_REGW, // input logic WriteMIPM, WriteSIPM, WriteUIPM, WriteMIEM, WriteSIEM, WriteUIEM ); logic MIntGlobalEnM, SIntGlobalEnM; - (* mark_debug = "true" *) logic [11:0] PendingIntsM; + (* mark_debug = "true" *) logic [11:0] MPendingIntsM, SPendingIntsM; //logic InterruptM; logic [`XLEN-1:0] PrivilegedTrapVector, PrivilegedVectoredTrapVector; logic Exception1M; @@ -67,11 +65,13 @@ module trap ( // interrupt if any sources are pending // & with a M stage valid bit to avoid interrupts from interrupt a nonexistent flushed instruction (in the M stage) // & with ~CommittedM to make sure MEPC isn't chosen so as to rerun the same instr twice + // MPendingIntsM[i] = ((priv == M & mstatus.MIE) | (priv < M)) & mip[i] & mie[i] & ~mideleg[i] + // Sinterrupt[i] = ((priv == S & sstatus.SIE) | (priv < S)) & sip[i] & sie[i] assign MIntGlobalEnM = (PrivilegeModeW != `M_MODE) | STATUS_MIE; // if M ints enabled or lower priv 3.1.9 assign SIntGlobalEnM = (PrivilegeModeW == `U_MODE) | ((PrivilegeModeW == `S_MODE) & STATUS_SIE); // if in lower priv mode, or if S ints enabled and not in higher priv mode 3.1.9 - assign PendingIntsM = ((MIP_REGW & MIE_REGW) & ({12{MIntGlobalEnM}} & 12'h888)) | ((SIP_REGW & SIE_REGW) & ({12{SIntGlobalEnM}} & 12'h222)); - assign PendingInterruptM = (|PendingIntsM) & InstrValidM; - assign InterruptM = PendingInterruptM & ~(CommittedM); // *** RT. temporary hack to prevent integer division from having an interrupt during divide. + assign MPendingIntsM = {12{MIntGlobalEnM}} & MIP_REGW & MIE_REGW & ~MIDELEG_REGW; + assign SPendingIntsM = {12{SIntGlobalEnM}} & SIP_REGW & SIE_REGW; + assign InterruptM = (|MPendingIntsM || |SPendingIntsM) && InstrValidM && ~(CommittedM); // *** RT. CommittedM is a temporary hack to prevent integer division from having an interrupt during divide. // Trigger Traps and RET // According to RISC-V Spec Section 1.6, exceptions are caused by instructions. Interrupts are external asynchronous. @@ -119,12 +119,15 @@ module trap ( // Exceptions are of lower priority than all interrupts (3.1.9) always_comb if (reset) CauseM = 0; // hard reset 3.3 - else if (PendingIntsM[11]) CauseM = (1 << (`XLEN-1)) + 11; // Machine External Int - else if (PendingIntsM[3]) CauseM = (1 << (`XLEN-1)) + 3; // Machine Sw Int - else if (PendingIntsM[7]) CauseM = (1 << (`XLEN-1)) + 7; // Machine Timer Int - else if (PendingIntsM[9]) CauseM = (1 << (`XLEN-1)) + 9; // Supervisor External Int - else if (PendingIntsM[1]) CauseM = (1 << (`XLEN-1)) + 1; // Supervisor Sw Int - else if (PendingIntsM[5]) CauseM = (1 << (`XLEN-1)) + 5; // Supervisor Timer Int + else if (MPendingIntsM[11]) CauseM = (1 << (`XLEN-1)) + 11; // Machine External Int + else if (MPendingIntsM[3]) CauseM = (1 << (`XLEN-1)) + 3; // Machine Sw Int + else if (MPendingIntsM[7]) CauseM = (1 << (`XLEN-1)) + 7; // Machine Timer Int + else if (MPendingIntsM[9]) CauseM = (1 << (`XLEN-1)) + 9; // Supervisor External Int handled by M-mode + else if (MPendingIntsM[1]) CauseM = (1 << (`XLEN-1)) + 1; // Supervisor Sw Int handled by M-mode + else if (MPendingIntsM[5]) CauseM = (1 << (`XLEN-1)) + 5; // Supervisor Timer Int handled by M-mode + else if (SPendingIntsM[9]) CauseM = (1 << (`XLEN-1)) + 9; // Supervisor External Int handled by S-mode + else if (SPendingIntsM[1]) CauseM = (1 << (`XLEN-1)) + 1; // Supervisor Sw Int handled by S-mode + else if (SPendingIntsM[5]) CauseM = (1 << (`XLEN-1)) + 5; // Supervisor Timer Int handled by S-mode else if (InstrPageFaultM) CauseM = 12; else if (InstrAccessFaultM) CauseM = 1; else if (InstrMisalignedFaultM) CauseM = 0; diff --git a/pipelined/src/uncore/plic.sv b/pipelined/src/uncore/plic.sv index cccbe75cf..4db7e8a0e 100644 --- a/pipelined/src/uncore/plic.sv +++ b/pipelined/src/uncore/plic.sv @@ -57,7 +57,7 @@ module plic ( input logic UARTIntr,GPIOIntr, output logic [`XLEN-1:0] HREADPLIC, output logic HRESPPLIC, HREADYPLIC, - output logic ExtIntM, ExtIntS); + output logic MExtIntM, SExtIntM); logic memwrite, memread, initTrans; logic [23:0] entry, entryd; @@ -253,10 +253,10 @@ module plic ( threshMask[ctx][2] = (intThreshold[ctx] != 2) & threshMask[ctx][3]; threshMask[ctx][1] = (intThreshold[ctx] != 1) & threshMask[ctx][2]; end - // is the max priority > threshold? - // *** would it be any better to first priority encode maxPriority into binary and then ">" with threshold? - end - assign ExtIntM = |(threshMask[0] & priorities_with_irqs[0]); - assign ExtIntS = |(threshMask[1] & priorities_with_irqs[1]); + end + // is the max priority > threshold? + // *** would it be any better to first priority encode maxPriority into binary and then ">" with threshold? + assign MExtIntM = |(threshMask[0] & priorities_with_irqs[0]); + assign SExtIntM = |(threshMask[1] & priorities_with_irqs[1]); endmodule diff --git a/pipelined/src/uncore/uncore.sv b/pipelined/src/uncore/uncore.sv index f48b96963..17daf50b1 100644 --- a/pipelined/src/uncore/uncore.sv +++ b/pipelined/src/uncore/uncore.sv @@ -55,7 +55,7 @@ module uncore ( input logic [3:0] HSIZED, input logic HWRITED, // peripheral pins - output logic TimerIntM, SwIntM, ExtIntM, ExtIntS, + output logic TimerIntM, SwIntM, MExtIntM, SExtIntM, input logic [31:0] GPIOPinsIn, output logic [31:0] GPIOPinsOut, GPIOPinsEn, input logic UARTSin, @@ -133,10 +133,10 @@ module uncore ( .HWRITE, .HREADY, .HTRANS, .HWDATA, .UARTIntr, .GPIOIntr, .HREADPLIC, .HRESPPLIC, .HREADYPLIC, - .ExtIntM, .ExtIntS); + .MExtIntM, .SExtIntM); end else begin : plic - assign ExtIntM = 0; - assign ExtIntS = 0; + assign MExtIntM = 0; + assign SExtIntM = 0; end if (`GPIO_SUPPORTED == 1) begin : gpio gpio gpio( diff --git a/pipelined/src/wally/wallypipelinedcore.sv b/pipelined/src/wally/wallypipelinedcore.sv index dd07949bc..43b61e6d5 100644 --- a/pipelined/src/wally/wallypipelinedcore.sv +++ b/pipelined/src/wally/wallypipelinedcore.sv @@ -34,7 +34,7 @@ module wallypipelinedcore ( input logic clk, reset, // Privileged - input logic TimerIntM, ExtIntM, ExtIntS, SwIntM, + input logic TimerIntM, MExtIntM, SExtIntM, SwIntM, input logic [63:0] MTIME_CLINT, // Bus Interface input logic [`AHBW-1:0] HRDATA, @@ -157,7 +157,6 @@ module wallypipelinedcore ( logic [2:0] LSUBusSize; logic ExceptionM; - logic PendingInterruptM; logic DCacheMiss; logic DCacheAccess; logic ICacheMiss; @@ -170,7 +169,7 @@ module wallypipelinedcore ( .StallF, .StallD, .StallE, .StallM, .StallW, .FlushF, .FlushD, .FlushE, .FlushM, .FlushW, - .ExceptionM, .PendingInterruptM, + .ExceptionM, // Fetch .IFUBusHRDATA, .IFUBusAck, .PCF, .IFUBusAdr, .IFUBusRead, .IFUStallF, @@ -331,7 +330,7 @@ module wallypipelinedcore ( .InstrPageFaultF, .LoadPageFaultM, .StoreAmoPageFaultM, .InstrMisalignedFaultM, .IllegalIEUInstrFaultD, .IllegalFPUInstrD, .LoadMisalignedFaultM, .StoreAmoMisalignedFaultM, - .TimerIntM, .ExtIntM, .ExtIntS, .SwIntM, + .TimerIntM, .MExtIntM, .SExtIntM, .SwIntM, .MTIME_CLINT, .InstrMisalignedAdrM, .IEUAdrM, .SetFflagsM, @@ -339,7 +338,7 @@ module wallypipelinedcore ( // *** do these need to be split up into one for dmem and one for ifu? // instead, could we only care about the instr and F pins that come from ifu and only care about the load/store and m pins that come from dmem? .InstrAccessFaultF, .LoadAccessFaultM, .StoreAmoAccessFaultM, - .ExceptionM, .PendingInterruptM, .IllegalFPUInstrE, + .ExceptionM, .IllegalFPUInstrE, .PrivilegeModeW, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, diff --git a/pipelined/src/wally/wallypipelinedsoc.sv b/pipelined/src/wally/wallypipelinedsoc.sv index 0d844d3cf..f199fe3e3 100644 --- a/pipelined/src/wally/wallypipelinedsoc.sv +++ b/pipelined/src/wally/wallypipelinedsoc.sv @@ -74,7 +74,7 @@ module wallypipelinedsoc ( logic HRESP; logic TimerIntM, SwIntM; // from CLINT logic [63:0] MTIME_CLINT; // from CLINT to CSRs - logic ExtIntM,ExtIntS; // from PLIC + logic MExtIntM,SExtIntM; // from PLIC logic [2:0] HADDRD; logic [3:0] HSIZED; logic HWRITED; @@ -84,7 +84,7 @@ module wallypipelinedsoc ( // instantiate processor and memories wallypipelinedcore core(.clk, .reset, - .TimerIntM, .ExtIntM, .ExtIntS, .SwIntM, + .TimerIntM, .MExtIntM, .SExtIntM, .SwIntM, .MTIME_CLINT, .HRDATA, .HREADY, .HRESP, .HCLK, .HRESETn, .HADDR, .HWDATA, .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, @@ -94,7 +94,7 @@ module wallypipelinedsoc ( uncore uncore(.HCLK, .HRESETn, .TIMECLK, .HADDR, .HWDATA, .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, .HRDATAEXT, .HREADYEXT, .HRESPEXT, .HRDATA, .HREADY, .HRESP, .HADDRD, .HSIZED, .HWRITED, - .TimerIntM, .SwIntM, .ExtIntM, .ExtIntS, .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn, .UARTSin, .UARTSout, .MTIME_CLINT, + .TimerIntM, .SwIntM, .MExtIntM, .SExtIntM, .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn, .UARTSin, .UARTSout, .MTIME_CLINT, .HSELEXT, .SDCCmdOut, .SDCCmdOE, .SDCCmdIn, .SDCDatIn, .SDCCLK diff --git a/pipelined/testbench/testbench-linux.sv b/pipelined/testbench/testbench-linux.sv index 50893cf65..8de0f90eb 100644 --- a/pipelined/testbench/testbench-linux.sv +++ b/pipelined/testbench/testbench-linux.sv @@ -357,7 +357,7 @@ module testbench; initial begin force dut.core.priv.priv.SwIntM = 0; force dut.core.priv.priv.TimerIntM = 0; - force dut.core.priv.priv.ExtIntM = 0; + force dut.core.priv.priv.MExtIntM = 0; $sformat(testvectorDir,"%s/linux-testvectors/",RISCV_DIR); $sformat(linuxImageDir,"%s/buildroot/output/images/",RISCV_DIR); if (CHECKPOINT!=0) From 471f204c4811ee2f1f7dabb96feff18357eed686 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Wed, 30 Mar 2022 17:29:48 -0500 Subject: [PATCH 13/18] Added bootrom.txt. --- fpga/generator/bootrom.txt | 42 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 fpga/generator/bootrom.txt diff --git a/fpga/generator/bootrom.txt b/fpga/generator/bootrom.txt new file mode 100644 index 000000000..b49f25c09 --- /dev/null +++ b/fpga/generator/bootrom.txt @@ -0,0 +1,42 @@ +94e1819300002197 +4281420141014081 +4481440143814301 +4681460145814501 +4881480147814701 +4a814a0149814901 +4c814c014b814b01 +4e814e014d814d01 +0110011b4f814f01 +059b45011161016e +0004063705fe0010 +05a000ef8006061b +0ff003930000100f +4e952e3110060e37 +c602829b0053f2b7 +2023fe02dfe312fd +829b0053f2b7007e +fe02dfe312fdc602 +4de31efd000e2023 +059bf1402573fdd0 +0000061705e20870 +0010029b01260613 +11010002806702fe +84b2842ae426e822 +892ee04aec064505 +06e000ef07e000ef +979334fd02905563 +07930177d4930204 +4089093394be2004 +04138522008905b3 +19e3014000ef2004 +64a2644260e2fe94 +6749808261056902 +dfed8b8510472783 +2423479110a73823 +10472783674910f7 +20058693ffed8b89 +05a1118737836749 +fed59be3fef5bc23 +1047278367498082 +67c98082dfed8b85 +0000808210a7a023 From 84a478c0537184787de73c5cc511e5b443cc54de Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Wed, 30 Mar 2022 17:48:44 -0500 Subject: [PATCH 14/18] Updated constraints file. --- fpga/constraints/debug2.xdc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fpga/constraints/debug2.xdc b/fpga/constraints/debug2.xdc index 4ace8b682..7cc4f8d1d 100644 --- a/fpga/constraints/debug2.xdc +++ b/fpga/constraints/debug2.xdc @@ -122,7 +122,7 @@ connect_debug_port u_ila_0/probe25 [get_nets [list {wallypipelinedsoc/uncore/sdc create_debug_port u_ila_0 probe set_property port_width 12 [get_debug_ports u_ila_0/probe26] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe26] -connect_debug_port u_ila_0/probe26 [get_nets [list {wallypipelinedsoc/core/priv.priv/trap/PendingIntsM[0]} {wallypipelinedsoc/core/priv.priv/trap/PendingIntsM[1]} {wallypipelinedsoc/core/priv.priv/trap/PendingIntsM[2]} {wallypipelinedsoc/core/priv.priv/trap/PendingIntsM[3]} {wallypipelinedsoc/core/priv.priv/trap/PendingIntsM[4]} {wallypipelinedsoc/core/priv.priv/trap/PendingIntsM[5]} {wallypipelinedsoc/core/priv.priv/trap/PendingIntsM[6]} {wallypipelinedsoc/core/priv.priv/trap/PendingIntsM[7]} {wallypipelinedsoc/core/priv.priv/trap/PendingIntsM[8]} {wallypipelinedsoc/core/priv.priv/trap/PendingIntsM[9]} {wallypipelinedsoc/core/priv.priv/trap/PendingIntsM[10]} {wallypipelinedsoc/core/priv.priv/trap/PendingIntsM[11]} ]] +connect_debug_port u_ila_0/probe26 [get_nets [list {wallypipelinedsoc/core/priv.priv/trap/MPendingIntsM[0]} {wallypipelinedsoc/core/priv.priv/trap/MPendingIntsM[1]} {wallypipelinedsoc/core/priv.priv/trap/MPendingIntsM[2]} {wallypipelinedsoc/core/priv.priv/trap/MPendingIntsM[3]} {wallypipelinedsoc/core/priv.priv/trap/MPendingIntsM[4]} {wallypipelinedsoc/core/priv.priv/trap/MPendingIntsM[5]} {wallypipelinedsoc/core/priv.priv/trap/MPendingIntsM[6]} {wallypipelinedsoc/core/priv.priv/trap/MPendingIntsM[7]} {wallypipelinedsoc/core/priv.priv/trap/MPendingIntsM[8]} {wallypipelinedsoc/core/priv.priv/trap/MPendingIntsM[9]} {wallypipelinedsoc/core/priv.priv/trap/MPendingIntsM[10]} {wallypipelinedsoc/core/priv.priv/trap/MPendingIntsM[11]} ]] create_debug_port u_ila_0 probe set_property port_width 64 [get_debug_ports u_ila_0/probe27] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe27] From dd3af17b3ffa4b1f7230fad9df0ab00c760d7e7d Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 31 Mar 2022 00:51:33 +0000 Subject: [PATCH 15/18] Added synthesis script for fma16 --- pipelined/src/fma/synth | 1 + 1 file changed, 1 insertion(+) create mode 100755 pipelined/src/fma/synth diff --git a/pipelined/src/fma/synth b/pipelined/src/fma/synth new file mode 100755 index 000000000..0ced41c8d --- /dev/null +++ b/pipelined/src/fma/synth @@ -0,0 +1 @@ +make -C ../../../synthDC synth DESIGN=fma16 From 285fc6fd4df09ab35eee4c084bdace588d908a46 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Thu, 31 Mar 2022 11:31:52 -0500 Subject: [PATCH 16/18] Modified clint to support all byte write sizes. --- pipelined/src/generic/flop/bram2p1r1w.sv | 18 +++++++++++-- pipelined/src/mmu/adrdecs.sv | 4 +-- pipelined/src/uncore/clint.sv | 34 +++++++++++++++++++----- pipelined/src/uncore/uncore.sv | 2 +- 4 files changed, 46 insertions(+), 12 deletions(-) diff --git a/pipelined/src/generic/flop/bram2p1r1w.sv b/pipelined/src/generic/flop/bram2p1r1w.sv index 89fe432a9..7bb79efe5 100644 --- a/pipelined/src/generic/flop/bram2p1r1w.sv +++ b/pipelined/src/generic/flop/bram2p1r1w.sv @@ -54,9 +54,22 @@ module bram2p1r1w input logic [ADDR_WIDTH-1:0] addrB, input logic [DATA_WIDTH-1:0] dinB ); - // Core Memory + + + + // *** TODO. +/* -----\/----- EXCLUDED -----\/----- + if(`SRAM) begin + // instanciate SRAM model + // need multiple SRAM instances to map into correct dimentions. + // also map the byte write enables onto bit write enables. + end else begin // FPGA or infered flip flop memory + // Core Memory + end + -----/\----- EXCLUDED -----/\----- */ + logic [DATA_WIDTH-1:0] RAM [(2**ADDR_WIDTH)-1:0]; - integer i; + integer i; initial begin if(PRELOAD_ENABLED) @@ -79,4 +92,5 @@ module bram2p1r1w end end end + endmodule // bytewrite_tdp_ram_rf diff --git a/pipelined/src/mmu/adrdecs.sv b/pipelined/src/mmu/adrdecs.sv index 5464f4ac6..0104ca578 100644 --- a/pipelined/src/mmu/adrdecs.sv +++ b/pipelined/src/mmu/adrdecs.sv @@ -37,7 +37,6 @@ module adrdecs ( input logic [1:0] Size, output logic [8:0] SelRegions ); - logic [3:0] clintaccesssize; // Determine which region of physical memory (if any) is being accessed // *** eventually uncomment Access signals @@ -45,8 +44,7 @@ module adrdecs ( adrdec boottimdec(PhysicalAddress, `BOOTROM_BASE, `BOOTROM_RANGE, `BOOTROM_SUPPORTED, /*1'b1*/AccessRX, Size, 4'b1111, SelRegions[6]); adrdec timdec(PhysicalAddress, `RAM_BASE, `RAM_RANGE, `RAM_SUPPORTED, /*1'b1*/AccessRWX, Size, 4'b1111, SelRegions[5]); - assign clintaccesssize = (`XLEN==64) ? 4'b1000 : 4'b0100; - adrdec clintdec(PhysicalAddress, `CLINT_BASE, `CLINT_RANGE, `CLINT_SUPPORTED, AccessRW, Size, clintaccesssize, SelRegions[4]); + adrdec clintdec(PhysicalAddress, `CLINT_BASE, `CLINT_RANGE, `CLINT_SUPPORTED, AccessRW, Size, 4'b1111, SelRegions[4]); adrdec gpiodec(PhysicalAddress, `GPIO_BASE, `GPIO_RANGE, `GPIO_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[3]); adrdec uartdec(PhysicalAddress, `UART_BASE, `UART_RANGE, `UART_SUPPORTED, AccessRW, Size, 4'b0001, SelRegions[2]); adrdec plicdec(PhysicalAddress, `PLIC_BASE, `PLIC_RANGE, `PLIC_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[1]); diff --git a/pipelined/src/uncore/clint.sv b/pipelined/src/uncore/clint.sv index be40d1521..f3ee4f5c1 100644 --- a/pipelined/src/uncore/clint.sv +++ b/pipelined/src/uncore/clint.sv @@ -35,6 +35,7 @@ module clint ( input logic HCLK, HRESETn, TIMECLK, input logic HSELCLINT, input logic [15:0] HADDR, + input logic [3:0] HSIZED, input logic HWRITE, input logic [`XLEN-1:0] HWDATA, input logic HREADY, @@ -50,6 +51,8 @@ module clint ( logic memwrite; logic initTrans; logic [63:0] MTIMECMP; + logic [`XLEN/8-1:0] ByteMaskM; + integer i; assign initTrans = HREADY & HSELCLINT & (HTRANS != 2'b00); // entryd and memwrite are delayed by a cycle because AHB controller waits a cycle before outputting write data @@ -63,6 +66,9 @@ module clint ( if (`XLEN==64) assign #2 entry = {HADDR[15:3], 3'b000}; else assign #2 entry = {HADDR[15:2], 2'b00}; + swbytemask swbytemask(.HSIZED, .HADDRD(entryd[2:0]), .ByteMask(ByteMaskM)); + + // DH 2/20/21: Eventually allow MTIME to run off a separate clock // This will require synchronizing MTIME to the system clock // before it is read or compared to MTIMECMP. @@ -86,7 +92,11 @@ module clint ( // MTIMECMP is not reset end else if (memwrite) begin if (entryd == 16'h0000) MSIP <= HWDATA[0]; - if (entryd == 16'h4000) MTIMECMP <= HWDATA; + if (entryd == 16'h4000) begin + for(i=0;i<`XLEN/8;i++) + if(ByteMaskM[i]) + MTIMECMP[i*8 +: 8] <= HWDATA[i*8 +: 8]; + end end // eventually replace MTIME logic below with timereg @@ -98,7 +108,9 @@ module clint ( // MTIMECMP is not reset end else if (memwrite & entryd == 16'hBFF8) begin // MTIME Counter. Eventually change this to run off separate clock. Synchronization then needed - MTIME <= HWDATA; + for(i=0;i<`XLEN/8;i++) + if(ByteMaskM[i]) + MTIME[i*8 +: 8] <= HWDATA[i*8 +: 8]; end else MTIME <= MTIME + 1; end else begin:clint // 32-bit always @(posedge HCLK) begin @@ -118,8 +130,14 @@ module clint ( // MTIMECMP is not reset ***? end else if (memwrite) begin if (entryd == 16'h0000) MSIP <= HWDATA[0]; - if (entryd == 16'h4000) MTIMECMP[31:0] <= HWDATA; - if (entryd == 16'h4004) MTIMECMP[63:32] <= HWDATA; + if (entryd == 16'h4000) + for(i=0;i<`XLEN/8;i++) + if(ByteMaskM[i]) + MTIMECMP[i*8 +: 8] <= HWDATA[i*8 +: 8]; + if (entryd == 16'h4004) + for(i=0;i<`XLEN/8;i++) + if(ByteMaskM[i]) + MTIMECMP[32 + i*8 +: 8] <= HWDATA[i*8 +: 8]; // MTIME Counter. Eventually change this to run off separate clock. Synchronization then needed end @@ -130,10 +148,14 @@ module clint ( MTIME <= 0; // MTIMECMP is not reset end else if (memwrite & (entryd == 16'hBFF8)) begin - MTIME[31:0] <= HWDATA; + for(i=0;i<`XLEN/8;i++) + if(ByteMaskM[i]) + MTIME[i*8 +: 8] <= HWDATA[i*8 +: 8]; end else if (memwrite & (entryd == 16'hBFFC)) begin // MTIME Counter. Eventually change this to run off separate clock. Synchronization then needed - MTIME[63:32]<= HWDATA; + for(i=0;i<`XLEN/8;i++) + if(ByteMaskM[i]) + MTIME[32 + i*8 +: 8]<= HWDATA[i*8 +: 8]; end else MTIME <= MTIME + 1; end diff --git a/pipelined/src/uncore/uncore.sv b/pipelined/src/uncore/uncore.sv index 17daf50b1..7649745bc 100644 --- a/pipelined/src/uncore/uncore.sv +++ b/pipelined/src/uncore/uncore.sv @@ -116,7 +116,7 @@ module uncore ( clint clint( .HCLK, .HRESETn, .TIMECLK, .HSELCLINT, .HADDR(HADDR[15:0]), .HWRITE, - .HWDATA, .HREADY, .HTRANS, + .HWDATA, .HREADY, .HTRANS, .HSIZED, .HREADCLINT, .HRESPCLINT, .HREADYCLINT, .MTIME(MTIME_CLINT), From c7043e4d63cea7e503ab146b35bdce9250cfb981 Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 31 Mar 2022 17:00:38 +0000 Subject: [PATCH 17/18] Added SystemVerilog flag to fma.do so that fma16 compiles properly --- pipelined/src/fma/fma.do | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipelined/src/fma/fma.do b/pipelined/src/fma/fma.do index 6e6863d5f..4a23facf6 100644 --- a/pipelined/src/fma/fma.do +++ b/pipelined/src/fma/fma.do @@ -8,7 +8,7 @@ onbreak {resume} # create library vlib worklib -vlog -lint -work worklib fma16.v testbench.v +vlog -lint -sv -work worklib fma16.v testbench.v vopt +acc worklib.testbench_fma16 -work worklib -o testbenchopt vsim -lib worklib testbenchopt From 0f7e995055f84f2fe44b18bb02e65e9daf8ecc8d Mon Sep 17 00:00:00 2001 From: bbracker Date: Thu, 31 Mar 2022 13:46:24 -0700 Subject: [PATCH 18/18] simplify plic logic --- pipelined/src/uncore/plic.sv | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/pipelined/src/uncore/plic.sv b/pipelined/src/uncore/plic.sv index 4db7e8a0e..082664dd3 100644 --- a/pipelined/src/uncore/plic.sv +++ b/pipelined/src/uncore/plic.sv @@ -176,11 +176,7 @@ module plic ( end // pending interrupt requests - assign nextIntPending = - (intPending | // existing pending requests - (requests & ~intInProgress)) & // assert new requests (if they aren't already being serviced) - ~({`N{((entry == 24'h200004) & memread)}} << (intClaim[0]-1)) & // deassert requests that just completed - ~({`N{((entry == 24'h201004) & memread)}} << (intClaim[1]-1)); + assign nextIntPending = (intPending | requests) & ~intInProgress; flopr #(`N) intPendingFlop(HCLK,~HRESETn,nextIntPending,intPending); // context-dependent signals