mirror of
				https://github.com/openhwgroup/cvw
				synced 2025-02-11 06:05:49 +00:00 
			
		
		
		
	Merge branch 'main' of https://github.com/davidharrishmc/riscv-wally into main
This commit is contained in:
		
						commit
						e3858c7008
					
				| @ -1,3 +1,6 @@ | ||||
| IMAGES := ${RISCV}/buildroot/output/images | ||||
| DIS := ${IMAGES}/disassembly | ||||
| 
 | ||||
| all: | ||||
| 	make disassemble | ||||
| 	make generate | ||||
| @ -7,15 +10,28 @@ generate: | ||||
| 	dtc -I dts -O dtb ../devicetree/wally-virt.dts > ${RISCV}/buildroot/output/images/wally-virt.dtb | ||||
| 
 | ||||
| disassemble: | ||||
| 	mkdir ${RISCV}/buildroot/output/images/disassembly | ||||
| 	# fw_jump | ||||
| 	riscv64-unknown-elf-objdump -D ${RISCV}/buildroot/output/images/fw_jump.elf >> ${RISCV}/buildroot/output/images/disassembly/fw_jump.objdump | ||||
| 	# vmlinux | ||||
| 	riscv64-unknown-elf-objdump -D ${RISCV}/buildroot/output/images/vmlinux >> ${RISCV}/buildroot/output/images/disassembly/vmlinux.objdump | ||||
| 	mkdir -p ${DIS} | ||||
| 	# disassemblies | ||||
| 	make -j ${DIS}/fw_jump.objdump ${DIS}/vmlinux.objdump ${DIS}/busybox.objdump | ||||
| 	# filesystem | ||||
| 	mkdir ${RISCV}/buildroot/output/images/disassembly/rootfs | ||||
| 	-cd ${RISCV}/buildroot/output/images/disassembly/rootfs; cpio -idv < ../../rootfs.cpio | ||||
| 	make ${DIS}/rootfs/bin/busybox | ||||
| 	# mkdir -p ${DIS}/rootfs | ||||
| 	# -cd ${DIS}/rootfs; cpio -id --nonmatching 'dev/console' < ../../rootfs.cpio | ||||
| 
 | ||||
| ${DIS}/fw_jump.objdump: ${IMAGES}/fw_jump.elf | ||||
| 	riscv64-unknown-elf-objdump -D ${IMAGES}/fw_jump.elf >> ${DIS}/fw_jump.objdump | ||||
| 
 | ||||
| ${DIS}/vmlinux.objdump: ${IMAGES}/vmlinux | ||||
| 	riscv64-unknown-elf-objdump -D ${IMAGES}/vmlinux >> ${DIS}/vmlinux.objdump | ||||
| 
 | ||||
| ${DIS}/busybox.objdump: ${DIS}/rootfs/bin/busybox | ||||
| 	riscv64-unknown-elf-objdump -D ${DIS}/rootfs/bin/busybox >> ${DIS}/busybox.objdump | ||||
| 
 | ||||
| ${DIS}/rootfs/bin/busybox: | ||||
| 	mkdir -p ${DIS}/rootfs | ||||
| 	-cd ${DIS}/rootfs; cpio -id --nonmatching 'dev/console' < ../../rootfs.cpio | ||||
| 
 | ||||
| 
 | ||||
| clean: | ||||
| 	rm ${RISCV}/buildroot/output/images/wally-virt.dtb | ||||
| 	rm -rf ${RISCV}/buildroot/output/images/disassembly | ||||
| 	rm -f ${IMAGES}/wally-virt.dtb | ||||
| 	rm -rf ${DIS} | ||||
|  | ||||
| @ -37,7 +37,8 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} { | ||||
|     vopt +acc work_${1}_${2}.testbench -work work_${1}_${2} -G INSTR_LIMIT=$3 -G INSTR_WAVEON=$4 -G CHECKPOINT=$5 -o testbenchopt  | ||||
|     vsim -lib work_${1}_${2} testbenchopt -suppress 8852,12070,3084 | ||||
| 
 | ||||
|     #-- Run the Simulation  | ||||
|     #-- Run the Simulation | ||||
|     run -all | ||||
|     add log -recursive /* | ||||
|     do linux-wave.do | ||||
|     run -all | ||||
|  | ||||
| @ -76,15 +76,14 @@ module ifu ( | ||||
| 	input logic [1:0] 			STATUS_MPP, | ||||
| 	input logic 				ITLBWriteF, ITLBFlushF, | ||||
| 	output logic 				ITLBMissF, InstrDAPageFaultF, | ||||
|   // pmp/pma (inside mmu) signals.  *** temporarily from AHB bus but eventually replace with internal versions pre H
 | ||||
| 	input 						var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], | ||||
| 	input 						var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0],  | ||||
| 	output logic 				InstrAccessFaultF, | ||||
|     output logic                ICacheAccess, | ||||
|     output logic                ICacheMiss | ||||
| ); | ||||
| 
 | ||||
| (* mark_debug = "true" *)  logic [`XLEN-1:0]            PCCorrectE, UnalignedPCNextF, PCNextF; | ||||
|   localparam                    CACHE_ENABLED = `IMEM == `MEM_CACHE; | ||||
|   (* mark_debug = "true" *)  logic [`XLEN-1:0]            PCCorrectE, UnalignedPCNextF, PCNextF; | ||||
|   logic                        BranchMisalignedFaultE; | ||||
|   logic                        PrivilegedChangePCM; | ||||
|   logic                        IllegalCompInstrD; | ||||
| @ -120,14 +119,14 @@ module ifu ( | ||||
|   assign PCFExt = {2'b00, PCFSpill}; | ||||
| 
 | ||||
|   /////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
|   // Spill Support  *** add other banners
 | ||||
|   // Spill Support
 | ||||
|   /////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
|   if(`C_SUPPORTED) begin : SpillSupport | ||||
| 
 | ||||
|     spillsupport spillsupport(.clk, .reset, .StallF, .PCF, .PCPlusUpperF, .PCNextF, .InstrRawF, | ||||
|                               .IFUCacheBusStallF, .ITLBMissF, .PCNextFSpill, .PCFSpill, | ||||
|                               .SelNextSpillF, .PostSpillInstrRawF, .CompressedF); | ||||
|       .InstrDAPageFaultF, .IFUCacheBusStallF, .ITLBMissF, .PCNextFSpill, .PCFSpill, | ||||
|       .SelNextSpillF, .PostSpillInstrRawF, .CompressedF); | ||||
|   end else begin : NoSpillSupport | ||||
|     assign PCNextFSpill = PCNextF; | ||||
|     assign PCFSpill = PCF; | ||||
| @ -161,7 +160,7 @@ module ifu ( | ||||
|          .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW); | ||||
| 
 | ||||
|   end else begin | ||||
|     assign {ITLBMissF, InstrAccessFaultF, InstrPageFaultF} = '0; | ||||
|     assign {ITLBMissF, InstrAccessFaultF, InstrPageFaultF, InstrDAPageFaultF} = '0; | ||||
|     assign PCPF = PCFExt[`PA_BITS-1:0]; | ||||
|     assign CacheableF = '1; | ||||
|   end | ||||
| @ -182,8 +181,8 @@ module ifu ( | ||||
|               .DCacheCommittedM(), .DCacheMiss(ICacheMiss), .DCacheAccess(ICacheAccess)); | ||||
|      | ||||
|   end else begin : bus | ||||
|     localparam integer   WORDSPERLINE = (`IMEM == `MEM_CACHE) ? `ICACHE_LINELENINBITS/`XLEN : 1; | ||||
|     localparam integer   LINELEN = (`IMEM == `MEM_CACHE) ? `ICACHE_LINELENINBITS : `XLEN; | ||||
|     localparam integer   WORDSPERLINE = (CACHE_ENABLED) ? `ICACHE_LINELENINBITS/`XLEN : 1; | ||||
|     localparam integer   LINELEN = (CACHE_ENABLED) ? `ICACHE_LINELENINBITS : `XLEN; | ||||
|     localparam integer   LOGWPL = (`DMEM == `MEM_CACHE) ? $clog2(WORDSPERLINE) : 1; | ||||
|     logic [LINELEN-1:0]  ReadDataLine; | ||||
|     logic [LINELEN-1:0]  ICacheBusWriteData; | ||||
| @ -193,7 +192,7 @@ module ifu ( | ||||
|     logic [31:0]         temp; | ||||
|     logic                SelUncachedAdr; | ||||
|      | ||||
|     busdp #(WORDSPERLINE, LINELEN, LOGWPL)  | ||||
|     busdp #(WORDSPERLINE, LINELEN, LOGWPL, CACHE_ENABLED)  | ||||
|     busdp(.clk, .reset, | ||||
|           .LSUBusHRDATA(IFUBusHRDATA), .LSUBusAck(IFUBusAck), .LSUBusWrite(), .LSUBusWriteCrit(), | ||||
|           .LSUBusRead(IFUBusRead), .LSUBusSize(),  | ||||
| @ -210,7 +209,7 @@ module ifu ( | ||||
|       .s(SelUncachedAdr), .y(AllInstrRawF[31:0])); | ||||
|      | ||||
| 
 | ||||
|     if(`IMEM == `MEM_CACHE) begin : icache | ||||
|     if(CACHE_ENABLED) begin : icache | ||||
|       logic [1:0] IFURWF; | ||||
|       assign IFURWF = CacheableF ? 2'b10 : 2'b00; | ||||
|        | ||||
| @ -247,18 +246,28 @@ module ifu ( | ||||
|    | ||||
|   flopenl #(32) AlignedInstrRawDFlop(clk, reset, ~StallD, FlushD ? nop : PostSpillInstrRawF, nop, InstrRawD); | ||||
| 
 | ||||
|   ////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
|   // PCNextF logic
 | ||||
|   ////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
|   assign PrivilegedChangePCM = RetM | TrapM; | ||||
| 
 | ||||
|   // *** look at moves pcmux2 and pcmux3 to generates as they are needed only on supporting caches and
 | ||||
|   // privilege instructions respectively.
 | ||||
|   mux2 #(`XLEN) pcmux1(.d0(PCNext0F), .d1(PCCorrectE), .s(BPPredWrongE), .y(PCNext1F)); | ||||
|   mux2 #(`XLEN) pcmux2(.d0(PCNext1F), .d1(PCBPWrongInvalidate), .s(InvalidateICacheM), .y(PCNext2F)); | ||||
|   mux2 #(`XLEN) pcmux3(.d0(PCNext2F), .d1(PrivilegedNextPCM), .s(PrivilegedChangePCM), .y(UnalignedPCNextF)); | ||||
|   if(CACHE_ENABLED) | ||||
|     mux2 #(`XLEN) pcmux2(.d0(PCNext1F), .d1(PCBPWrongInvalidate), .s(InvalidateICacheM),  | ||||
|       .y(PCNext2F)); | ||||
|   else assign PCNext2F = PCNext1F; | ||||
|   if(`ZICSR_SUPPORTED) | ||||
|     mux2 #(`XLEN) pcmux3(.d0(PCNext2F), .d1(PrivilegedNextPCM), .s(PrivilegedChangePCM),  | ||||
|       .y(UnalignedPCNextF)); | ||||
|   else assign UnalignedPCNextF = PCNext2F; | ||||
| 
 | ||||
|   assign  PCNextF = {UnalignedPCNextF[`XLEN-1:1], 1'b0}; // hart-SPEC p. 21 about 16-bit alignment
 | ||||
|   flopenl #(`XLEN) pcreg(clk, reset, ~StallF, PCNextF, `RESET_VECTOR, PCF); | ||||
| 
 | ||||
|   // branch and jump predictor
 | ||||
|   ////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
|   // Branch and Jump Predictor
 | ||||
|   ////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
|   if (`BPRED_ENABLED) begin : bpred | ||||
|     logic                        BPPredWrongM; | ||||
|     logic                        SelBPPredF; | ||||
| @ -295,6 +304,9 @@ module ifu ( | ||||
|       else        PCPlus2or4F = {PCF[`XLEN-1:2], 2'b10}; | ||||
|     else          PCPlus2or4F = {PCPlusUpperF, PCF[1:0]}; // add 4
 | ||||
| 
 | ||||
|   ////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
|   // Decode stage pipeline register and compressed instruction decoding.
 | ||||
|   ////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
|   // Decode stage pipeline register and logic
 | ||||
|   flopenrc #(`XLEN) PCDReg(clk, reset, FlushD, ~StallD, PCF, PCD); | ||||
|     | ||||
|  | ||||
| @ -42,6 +42,7 @@ module spillsupport ( | ||||
|   input logic [31:0]       InstrRawF, | ||||
|   input logic              IFUCacheBusStallF, | ||||
|   input logic              ITLBMissF,  | ||||
|   input logic              InstrDAPageFaultF,  | ||||
|   output logic [`XLEN-1:0] PCNextFSpill, | ||||
|   output logic [`XLEN-1:0] PCFSpill, | ||||
|   output logic             SelNextSpillF, | ||||
| @ -50,44 +51,41 @@ module spillsupport ( | ||||
| 
 | ||||
| 
 | ||||
|   localparam integer   SPILLTHRESHOLD = (`IMEM == `MEM_CACHE) ? `ICACHE_LINELENINBITS/32 : 1; | ||||
|   logic [`XLEN-1:0] PCPlus2F; | ||||
|   logic             TakeSpillF; | ||||
|   logic             SpillF; | ||||
|   logic             SelSpillF, SpillSaveF; | ||||
|   logic [15:0]      SpillDataLine0; | ||||
|   logic [`XLEN-1:0]    PCPlus2F; | ||||
|   logic                TakeSpillF; | ||||
|   logic                SpillF; | ||||
|   logic                SelSpillF, SpillSaveF; | ||||
|   logic [15:0]         SpillDataLine0; | ||||
|   typedef enum logic [1:0]     {STATE_READY, STATE_SPILL} statetype; | ||||
|   (* mark_debug = "true" *)  statetype CurrState, NextState; | ||||
| 
 | ||||
|   // *** PLACE ALL THIS IN A MODULE
 | ||||
|   // this exists only if there are compressed instructions.
 | ||||
|   // reuse PC+2/4 circuitry to avoid needing a second CPA to add 2
 | ||||
|   mux2 #(`XLEN) pcplus2mux(.d0({PCF[`XLEN-1:2], 2'b10}), .d1({PCPlusUpperF, 2'b00}), .s(PCF[1]), .y(PCPlus2F)); | ||||
|   mux2 #(`XLEN) pcnextspillmux(.d0(PCNextF), .d1(PCPlus2F), .s(SelNextSpillF), .y(PCNextFSpill)); | ||||
|   mux2 #(`XLEN) pcplus2mux(.d0({PCF[`XLEN-1:2], 2'b10}), .d1({PCPlusUpperF, 2'b00}),  | ||||
|     .s(PCF[1]), .y(PCPlus2F)); | ||||
|   mux2 #(`XLEN) pcnextspillmux(.d0(PCNextF), .d1(PCPlus2F), .s(SelNextSpillF), | ||||
|     .y(PCNextFSpill)); | ||||
|   mux2 #(`XLEN) pcspillmux(.d0(PCF), .d1(PCPlus2F), .s(SelSpillF), .y(PCFSpill)); | ||||
|    | ||||
|   assign SpillF = &PCF[$clog2(SPILLTHRESHOLD)+1:1]; | ||||
| 
 | ||||
|   typedef enum logic [1:0]     {STATE_SPILL_READY, STATE_SPILL_SPILL} statetype; | ||||
|   (* mark_debug = "true" *)  statetype CurrState, NextState; | ||||
| 
 | ||||
|   assign TakeSpillF = SpillF & ~IFUCacheBusStallF & ~(ITLBMissF | (`HPTW_WRITES_SUPPORTED & InstrDAPageFaultF)); | ||||
|    | ||||
|   always_ff @(posedge clk) | ||||
|     if (reset)    CurrState <= #1 STATE_SPILL_READY; | ||||
|     if (reset)    CurrState <= #1 STATE_READY; | ||||
|     else CurrState <= #1 NextState; | ||||
| 
 | ||||
|   assign TakeSpillF = SpillF & ~IFUCacheBusStallF & ~ITLBMissF; | ||||
|    | ||||
|   always_comb begin | ||||
|     case (CurrState) | ||||
|       STATE_SPILL_READY: if (TakeSpillF)                   NextState = STATE_SPILL_SPILL; | ||||
|       else                                                 NextState = STATE_SPILL_READY; | ||||
|       STATE_SPILL_SPILL: if(IFUCacheBusStallF | StallF)    NextState = STATE_SPILL_SPILL; | ||||
|       else                                                 NextState = STATE_SPILL_READY; | ||||
|       default:                                             NextState = STATE_SPILL_READY; | ||||
|       STATE_READY: if (TakeSpillF)                NextState = STATE_SPILL; | ||||
|                    else                           NextState = STATE_READY; | ||||
|       STATE_SPILL: if(IFUCacheBusStallF | StallF) NextState = STATE_SPILL; | ||||
|                    else                           NextState = STATE_READY; | ||||
|       default:                                    NextState = STATE_READY; | ||||
|     endcase | ||||
|   end | ||||
| 
 | ||||
|   assign SelSpillF = (CurrState == STATE_SPILL_SPILL); | ||||
|   assign SelNextSpillF = (CurrState == STATE_SPILL_READY & TakeSpillF) | | ||||
|                          (CurrState == STATE_SPILL_SPILL & IFUCacheBusStallF); | ||||
|   assign SpillSaveF = (CurrState == STATE_SPILL_READY) & TakeSpillF; | ||||
|   assign SelSpillF = (CurrState == STATE_SPILL); | ||||
|   assign SelNextSpillF = (CurrState == STATE_READY & TakeSpillF) | | ||||
|                          (CurrState == STATE_SPILL & IFUCacheBusStallF); | ||||
|   assign SpillSaveF = (CurrState == STATE_READY) & TakeSpillF; | ||||
| 
 | ||||
|   flopenr #(16) SpillInstrReg(.clk(clk), | ||||
|                               .en(SpillSaveF), | ||||
| @ -95,7 +93,8 @@ module spillsupport ( | ||||
|                               .d((`IMEM == `MEM_CACHE) ? InstrRawF[15:0] : InstrRawF[31:16]), | ||||
|                               .q(SpillDataLine0)); | ||||
| 
 | ||||
|   assign PostSpillInstrRawF = SpillF ? {InstrRawF[15:0], SpillDataLine0} : InstrRawF; | ||||
|   mux2 #(32) postspillmux(.d0(InstrRawF), .d1({InstrRawF[15:0], SpillDataLine0}), .s(SpillF), | ||||
|     .y(PostSpillInstrRawF)); | ||||
|   assign CompressedF = PostSpillInstrRawF[1:0] != 2'b11; | ||||
| 
 | ||||
| endmodule | ||||
|  | ||||
| @ -34,7 +34,7 @@ | ||||
| 
 | ||||
| `include "wally-config.vh" | ||||
| 
 | ||||
| module busdp #(parameter WORDSPERLINE, LINELEN, LOGWPL, LSU=0) | ||||
| module busdp #(parameter WORDSPERLINE, LINELEN, LOGWPL, CACHE_ENABLED) | ||||
|   ( | ||||
|   input logic                 clk, reset, | ||||
|   // bus interface
 | ||||
| @ -66,21 +66,21 @@ module busdp #(parameter WORDSPERLINE, LINELEN, LOGWPL, LSU=0) | ||||
|   output logic                BusCommittedM); | ||||
|    | ||||
| 
 | ||||
|   localparam integer   WordCountThreshold = (`DMEM == `MEM_CACHE) ? WORDSPERLINE - 1 : 0; | ||||
| 
 | ||||
|   localparam integer   WordCountThreshold = CACHE_ENABLED ? WORDSPERLINE - 1 : 0; | ||||
|   logic [`PA_BITS-1:0]        LocalLSUBusAdr; | ||||
|   genvar                      index; | ||||
| 
 | ||||
|   for (index = 0; index < WORDSPERLINE; index++) begin:fetchbuffer | ||||
|     flopen #(`XLEN) fb(.clk, .en(LSUBusAck & LSUBusRead & (index == WordCount)), | ||||
|                        .d(LSUBusHRDATA), .q(DCacheBusWriteData[(index+1)*`XLEN-1:index*`XLEN])); | ||||
|     logic [WORDSPERLINE-1:0] CaptureWord; | ||||
|     assign CaptureWord[index] = LSUBusAck & LSUBusRead & (index == WordCount); | ||||
|     flopen #(`XLEN) fb(.clk, .en(CaptureWord[index]), .d(LSUBusHRDATA), | ||||
|       .q(DCacheBusWriteData[(index+1)*`XLEN-1:index*`XLEN])); | ||||
|   end | ||||
|   mux2 #(`PA_BITS) localadrmux(DCacheBusAdr, LSUPAdrM, SelUncachedAdr, LocalLSUBusAdr); | ||||
|   assign LSUBusAdr = ({{`PA_BITS-LOGWPL{1'b0}}, WordCount} << $clog2(`XLEN/8)) + LocalLSUBusAdr; | ||||
|    mux2 #(3) lsubussizemux(.d0(`XLEN == 32 ? 3'b010 : 3'b011), .d1(LSUFunct3M),  | ||||
|   mux2 #(3) lsubussizemux(.d0(`XLEN == 32 ? 3'b010 : 3'b011), .d1(LSUFunct3M),  | ||||
|     .s(SelUncachedAdr), .y(LSUBusSize)); | ||||
| 
 | ||||
|   busfsm #(WordCountThreshold, LOGWPL, (`DMEM == `MEM_CACHE)) // *** cleanup  Icache? must fix.
 | ||||
|   busfsm #(WordCountThreshold, LOGWPL, CACHE_ENABLED)  | ||||
|   busfsm(.clk, .reset, .IgnoreRequest, .LSURWM, .DCacheFetchLine, .DCacheWriteLine, | ||||
| 		 .LSUBusAck, .CPUBusy, .CacheableM, .BusStall, .LSUBusWrite, .LSUBusWriteCrit, .LSUBusRead, | ||||
| 		 .DCacheBusAck, .BusCommittedM, .SelUncachedAdr, .WordCount); | ||||
|  | ||||
| @ -32,7 +32,7 @@ | ||||
| 
 | ||||
| 
 | ||||
| module busfsm #(parameter integer   WordCountThreshold, | ||||
| 				parameter integer LOGWPL, parameter logic CacheEnabled ) | ||||
| 				parameter integer LOGWPL, parameter logic CACHE_ENABLED ) | ||||
|   (input logic               clk, | ||||
|    input logic               reset, | ||||
| 
 | ||||
| @ -88,7 +88,7 @@ module busfsm #(parameter integer   WordCountThreshold, | ||||
|   assign WordCountFlag = (WordCount == WordCountThreshold[LOGWPL-1:0]); | ||||
|   assign CntEn = PreCntEn & LSUBusAck; | ||||
| 
 | ||||
|   assign UnCachedAccess = ~CacheEnabled | ~CacheableM; | ||||
|   assign UnCachedAccess = ~CACHE_ENABLED | ~CacheableM; | ||||
| 
 | ||||
|   always_ff @(posedge clk) | ||||
|     if (reset)    BusCurrState <= #1 STATE_BUS_READY; | ||||
| @ -96,27 +96,27 @@ module busfsm #(parameter integer   WordCountThreshold, | ||||
|    | ||||
|   always_comb begin | ||||
| 	case(BusCurrState) | ||||
| 	  STATE_BUS_READY:           if(IgnoreRequest)               BusNextState = STATE_BUS_READY; | ||||
| 	                             else if(LSURWM[0] & (UnCachedAccess)) BusNextState = STATE_BUS_UNCACHED_WRITE; | ||||
| 		                         else if(LSURWM[1] & (UnCachedAccess)) BusNextState = STATE_BUS_UNCACHED_READ; | ||||
| 	  STATE_BUS_READY:           if(IgnoreRequest)                   BusNextState = STATE_BUS_READY; | ||||
| 	                             else if(LSURWM[0] & UnCachedAccess) BusNextState = STATE_BUS_UNCACHED_WRITE; | ||||
| 		                         else if(LSURWM[1] & UnCachedAccess) BusNextState = STATE_BUS_UNCACHED_READ; | ||||
| 		                         else if(DCacheFetchLine)            BusNextState = STATE_BUS_FETCH; | ||||
| 		                         else if(DCacheWriteLine)            BusNextState = STATE_BUS_WRITE; | ||||
|                                  else                             BusNextState = STATE_BUS_READY; | ||||
|       STATE_BUS_UNCACHED_WRITE:  if(LSUBusAck)                   BusNextState = STATE_BUS_UNCACHED_WRITE_DONE; | ||||
| 		                         else                            BusNextState = STATE_BUS_UNCACHED_WRITE; | ||||
|       STATE_BUS_UNCACHED_READ:   if(LSUBusAck)                   BusNextState = STATE_BUS_UNCACHED_READ_DONE; | ||||
| 		                         else                            BusNextState = STATE_BUS_UNCACHED_READ; | ||||
|       STATE_BUS_UNCACHED_WRITE_DONE: if(CPUBusy)                 BusNextState = STATE_BUS_CPU_BUSY; | ||||
|                                      else                        BusNextState = STATE_BUS_READY; | ||||
|       STATE_BUS_UNCACHED_READ_DONE:  if(CPUBusy)                 BusNextState = STATE_BUS_CPU_BUSY; | ||||
|                                      else                        BusNextState = STATE_BUS_READY; | ||||
| 	  STATE_BUS_CPU_BUSY:            if(CPUBusy)                 BusNextState = STATE_BUS_CPU_BUSY; | ||||
|                                      else                        BusNextState = STATE_BUS_READY; | ||||
|       STATE_BUS_FETCH:           if (WordCountFlag & LSUBusAck)  BusNextState = STATE_BUS_READY; | ||||
| 	                             else                            BusNextState = STATE_BUS_FETCH; | ||||
|       STATE_BUS_WRITE:           if(WordCountFlag & LSUBusAck)   BusNextState = STATE_BUS_READY; | ||||
| 	                             else                            BusNextState = STATE_BUS_WRITE; | ||||
| 	  default:                                                   BusNextState = STATE_BUS_READY; | ||||
|                                  else                                BusNextState = STATE_BUS_READY; | ||||
|       STATE_BUS_UNCACHED_WRITE:  if(LSUBusAck)                       BusNextState = STATE_BUS_UNCACHED_WRITE_DONE; | ||||
| 		                         else                                BusNextState = STATE_BUS_UNCACHED_WRITE; | ||||
|       STATE_BUS_UNCACHED_READ:   if(LSUBusAck)                       BusNextState = STATE_BUS_UNCACHED_READ_DONE; | ||||
| 		                         else                                BusNextState = STATE_BUS_UNCACHED_READ; | ||||
|       STATE_BUS_UNCACHED_WRITE_DONE: if(CPUBusy)                     BusNextState = STATE_BUS_CPU_BUSY; | ||||
|                                      else                            BusNextState = STATE_BUS_READY; | ||||
|       STATE_BUS_UNCACHED_READ_DONE:  if(CPUBusy)                     BusNextState = STATE_BUS_CPU_BUSY; | ||||
|                                      else                            BusNextState = STATE_BUS_READY; | ||||
| 	  STATE_BUS_CPU_BUSY:            if(CPUBusy)                     BusNextState = STATE_BUS_CPU_BUSY; | ||||
|                                      else                            BusNextState = STATE_BUS_READY; | ||||
|       STATE_BUS_FETCH:           if (WordCountFlag & LSUBusAck)      BusNextState = STATE_BUS_READY; | ||||
| 	                             else                                BusNextState = STATE_BUS_FETCH; | ||||
|       STATE_BUS_WRITE:           if(WordCountFlag & LSUBusAck)       BusNextState = STATE_BUS_READY; | ||||
| 	                             else                                BusNextState = STATE_BUS_WRITE; | ||||
| 	  default:                                                       BusNextState = STATE_BUS_READY; | ||||
| 	endcase | ||||
|   end | ||||
| 
 | ||||
| @ -128,14 +128,14 @@ module busfsm #(parameter integer   WordCountThreshold, | ||||
| 					(BusCurrState == STATE_BUS_FETCH)  | | ||||
| 					(BusCurrState == STATE_BUS_WRITE); | ||||
|   assign PreCntEn = BusCurrState == STATE_BUS_FETCH | BusCurrState == STATE_BUS_WRITE; | ||||
|   assign UnCachedLSUBusWrite = (BusCurrState == STATE_BUS_READY & UnCachedAccess & (LSURWM[0] & ~IgnoreRequest)) | | ||||
|   assign UnCachedLSUBusWrite = (BusCurrState == STATE_BUS_READY & UnCachedAccess & LSURWM[0] & ~IgnoreRequest) | | ||||
| 							   (BusCurrState == STATE_BUS_UNCACHED_WRITE); | ||||
|   assign LSUBusWrite = UnCachedLSUBusWrite | (BusCurrState == STATE_BUS_WRITE); | ||||
|   assign LSUBusWriteCrit = (BusCurrState == STATE_BUS_READY & UnCachedAccess & (LSURWM[0])) | | ||||
|   assign LSUBusWriteCrit = (BusCurrState == STATE_BUS_READY & UnCachedAccess & LSURWM[0]) | | ||||
| 						   (BusCurrState == STATE_BUS_UNCACHED_WRITE) | | ||||
|                            (BusCurrState == STATE_BUS_WRITE); | ||||
| 
 | ||||
|   assign UnCachedLSUBusRead = (BusCurrState == STATE_BUS_READY & UnCachedAccess & (|LSURWM[1] & IgnoreRequest)) | | ||||
|   assign UnCachedLSUBusRead = (BusCurrState == STATE_BUS_READY & UnCachedAccess & LSURWM[1] & IgnoreRequest) | | ||||
| 							  (BusCurrState == STATE_BUS_UNCACHED_READ); | ||||
|   assign LSUBusRead = UnCachedLSUBusRead | (BusCurrState == STATE_BUS_FETCH) | (BusCurrState == STATE_BUS_READY & DCacheFetchLine); | ||||
| 
 | ||||
| @ -147,5 +147,5 @@ module busfsm #(parameter integer   WordCountThreshold, | ||||
| 						   BusCurrState == STATE_BUS_UNCACHED_READ_DONE | | ||||
| 						   BusCurrState == STATE_BUS_UNCACHED_WRITE | | ||||
| 						   BusCurrState == STATE_BUS_UNCACHED_WRITE_DONE) | | ||||
| 						  ~CacheEnabled; // if no dcache always select uncachedadr.
 | ||||
| 						  ~CACHE_ENABLED; // if no dcache always select uncachedadr.
 | ||||
| endmodule | ||||
|  | ||||
| @ -31,33 +31,44 @@ | ||||
| 
 | ||||
| `include "wally-config.vh" | ||||
| 
 | ||||
| module interlockfsm | ||||
|   (input logic clk, | ||||
|    input logic  reset, | ||||
|    input logic  AnyCPUReqM, | ||||
|    input logic  ITLBMissOrDAFaultF, | ||||
|    input logic  ITLBWriteF, | ||||
|    input logic  DTLBMissOrDAFaultM, | ||||
|    input logic  DTLBWriteM, | ||||
|    input logic  TrapM, | ||||
|    input logic  DCacheStallM, | ||||
| module interlockfsm( | ||||
|   input logic       clk, | ||||
|   input logic       reset, | ||||
|   input logic [1:0] MemRWM, | ||||
|   input logic [1:0] AtomicM, | ||||
|   input logic       ITLBMissOrDAFaultF, | ||||
|   input logic       ITLBWriteF, | ||||
|   input logic       DTLBMissOrDAFaultM, | ||||
|   input logic       DTLBWriteM, | ||||
|   input logic       TrapM, | ||||
|   input logic       DCacheStallM, | ||||
| 
 | ||||
|    output logic InterlockStall, | ||||
|    output logic SelReplayCPURequest, | ||||
|    output logic SelHPTW, | ||||
|    output logic IgnoreRequestTLB, | ||||
|    output logic IgnoreRequestTrapM); | ||||
|   output logic      InterlockStall, | ||||
|   output logic      SelReplayCPURequest, | ||||
|   output logic      SelHPTW, | ||||
|   output logic      IgnoreRequestTLB, | ||||
|   output logic      IgnoreRequestTrapM); | ||||
| 
 | ||||
|   logic             ToITLBMiss; | ||||
|   logic             ToITLBMissNoReplay; | ||||
|   logic             ToDTLBMiss; | ||||
|   logic             ToBoth; | ||||
|   logic             AnyCPUReqM; | ||||
| 
 | ||||
|   typedef enum logic[2:0]  {STATE_T0_READY, | ||||
| 				 STATE_T0_REPLAY, | ||||
| 				 STATE_T3_DTLB_MISS, | ||||
| 				 STATE_T4_ITLB_MISS, | ||||
| 				 STATE_T5_ITLB_MISS, | ||||
| 				 STATE_T7_DITLB_MISS} statetype; | ||||
|   typedef enum      logic[2:0]  {STATE_T0_READY, | ||||
| 				                 STATE_T0_REPLAY, | ||||
| 				                 STATE_T3_DTLB_MISS, | ||||
| 				                 STATE_T4_ITLB_MISS, | ||||
| 				                 STATE_T5_ITLB_MISS, | ||||
| 				                 STATE_T7_DITLB_MISS} statetype; | ||||
| 
 | ||||
|   (* mark_debug = "true" *)	  statetype InterlockCurrState, InterlockNextState; | ||||
| 
 | ||||
|   assign AnyCPUReqM = (|MemRWM) | (|AtomicM); | ||||
|   assign ToITLBMiss = ITLBMissOrDAFaultF & ~DTLBMissOrDAFaultM & AnyCPUReqM; | ||||
|   assign ToITLBMissNoReplay = ITLBMissOrDAFaultF & ~DTLBMissOrDAFaultM & ~AnyCPUReqM; | ||||
|   assign ToDTLBMiss = ~ITLBMissOrDAFaultF & DTLBMissOrDAFaultM & AnyCPUReqM; | ||||
|   assign ToBoth = ITLBMissOrDAFaultF & DTLBMissOrDAFaultM & AnyCPUReqM; | ||||
| 
 | ||||
|   always_ff @(posedge clk) | ||||
| 	if (reset)    InterlockCurrState <= #1 STATE_T0_READY; | ||||
| @ -65,23 +76,23 @@ module interlockfsm | ||||
| 
 | ||||
|   always_comb begin | ||||
| 	case(InterlockCurrState) | ||||
| 	  STATE_T0_READY: if (TrapM)                       InterlockNextState = STATE_T0_READY; | ||||
| 	  else if(~ITLBMissOrDAFaultF & DTLBMissOrDAFaultM & AnyCPUReqM)     InterlockNextState = STATE_T3_DTLB_MISS; | ||||
| 	  else if(ITLBMissOrDAFaultF & ~DTLBMissOrDAFaultM & ~AnyCPUReqM)    InterlockNextState = STATE_T4_ITLB_MISS; | ||||
|       else if(ITLBMissOrDAFaultF & ~DTLBMissOrDAFaultM & AnyCPUReqM)     InterlockNextState = STATE_T5_ITLB_MISS; | ||||
| 	  else if(ITLBMissOrDAFaultF & DTLBMissOrDAFaultM & AnyCPUReqM)      InterlockNextState = STATE_T7_DITLB_MISS; | ||||
| 	  else                                             InterlockNextState = STATE_T0_READY; | ||||
| 	  STATE_T0_REPLAY:       if(DCacheStallM)                                  InterlockNextState = STATE_T0_REPLAY; | ||||
| 	  else                                             InterlockNextState = STATE_T0_READY; | ||||
| 	  STATE_T3_DTLB_MISS:    if(DTLBWriteM)                                   InterlockNextState = STATE_T0_REPLAY; | ||||
| 	  else                                             InterlockNextState = STATE_T3_DTLB_MISS; | ||||
| 	  STATE_T4_ITLB_MISS:    if(ITLBWriteF)                                   InterlockNextState = STATE_T0_READY; | ||||
| 	  else                                             InterlockNextState = STATE_T4_ITLB_MISS; | ||||
| 	  STATE_T5_ITLB_MISS:    if(ITLBWriteF)                                   InterlockNextState = STATE_T0_REPLAY; | ||||
| 	  else                                             InterlockNextState = STATE_T5_ITLB_MISS; | ||||
| 	  STATE_T7_DITLB_MISS:   if(DTLBWriteM)                                   InterlockNextState = STATE_T5_ITLB_MISS; | ||||
| 	  else                                             InterlockNextState = STATE_T7_DITLB_MISS; | ||||
| 	  default: InterlockNextState = STATE_T0_READY; | ||||
| 	  STATE_T0_READY: if (TrapM)                  InterlockNextState = STATE_T0_READY; | ||||
| 	                  else if(ToDTLBMiss)         InterlockNextState = STATE_T3_DTLB_MISS; | ||||
| 	                  else if(ToITLBMissNoReplay) InterlockNextState = STATE_T4_ITLB_MISS; | ||||
|                       else if(ToITLBMiss)         InterlockNextState = STATE_T5_ITLB_MISS; | ||||
| 	                  else if(ToBoth)             InterlockNextState = STATE_T7_DITLB_MISS; | ||||
| 	                  else                        InterlockNextState = STATE_T0_READY; | ||||
| 	  STATE_T0_REPLAY:     if(DCacheStallM)       InterlockNextState = STATE_T0_REPLAY; | ||||
| 	                       else                   InterlockNextState = STATE_T0_READY; | ||||
| 	  STATE_T3_DTLB_MISS:  if(DTLBWriteM)         InterlockNextState = STATE_T0_REPLAY; | ||||
| 	                       else                   InterlockNextState = STATE_T3_DTLB_MISS; | ||||
| 	  STATE_T4_ITLB_MISS:  if(ITLBWriteF)         InterlockNextState = STATE_T0_READY; | ||||
| 	                       else                   InterlockNextState = STATE_T4_ITLB_MISS; | ||||
| 	  STATE_T5_ITLB_MISS:  if(ITLBWriteF)         InterlockNextState = STATE_T0_REPLAY; | ||||
| 	                       else                   InterlockNextState = STATE_T5_ITLB_MISS; | ||||
| 	  STATE_T7_DITLB_MISS: if(DTLBWriteM)         InterlockNextState = STATE_T5_ITLB_MISS; | ||||
| 	                       else                   InterlockNextState = STATE_T7_DITLB_MISS; | ||||
| 	  default:                                    InterlockNextState = STATE_T0_READY; | ||||
| 	endcase | ||||
|   end // always_comb
 | ||||
| 	   | ||||
|  | ||||
| @ -82,6 +82,7 @@ module lsu ( | ||||
|    input var                logic [`XLEN-1:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0] // *** this one especially has a large note attached to it in pmpchecker.
 | ||||
|   ); | ||||
| 
 | ||||
|   localparam                CACHE_ENABLED = `DMEM == `MEM_CACHE; | ||||
|   logic [`XLEN+1:0]         IEUAdrExtM; | ||||
|   logic [`PA_BITS-1:0]      LSUPAdrM; | ||||
|   logic                     DTLBMissM; | ||||
| @ -192,9 +193,9 @@ module lsu ( | ||||
|               .DCacheMiss, .DCacheAccess); | ||||
|     assign SelUncachedAdr = '0; // value does not matter.
 | ||||
|   end else begin : bus   | ||||
|     localparam integer   WORDSPERLINE = (`DMEM == `MEM_CACHE) ? `DCACHE_LINELENINBITS/`XLEN : 1; | ||||
|     localparam integer   LINELEN = (`DMEM == `MEM_CACHE) ? `DCACHE_LINELENINBITS : `XLEN; | ||||
|     localparam integer   LOGWPL = (`DMEM == `MEM_CACHE) ? $clog2(WORDSPERLINE) : 1; | ||||
|     localparam integer   WORDSPERLINE = (CACHE_ENABLED) ? `DCACHE_LINELENINBITS/`XLEN : 1; | ||||
|     localparam integer   LINELEN = (CACHE_ENABLED) ? `DCACHE_LINELENINBITS : `XLEN; | ||||
|     localparam integer   LOGWPL = (CACHE_ENABLED) ? $clog2(WORDSPERLINE) : 1; | ||||
|     logic [LINELEN-1:0]  ReadDataLineM; | ||||
|     logic [LINELEN-1:0]  DCacheBusWriteData; | ||||
|     logic [`PA_BITS-1:0] DCacheBusAdr; | ||||
| @ -206,7 +207,7 @@ module lsu ( | ||||
|     logic                SelBus; | ||||
|     logic [LOGWPL-1:0]   WordCount; | ||||
|              | ||||
|     busdp #(WORDSPERLINE, LINELEN, LOGWPL, 1) busdp( | ||||
|     busdp #(WORDSPERLINE, LINELEN, LOGWPL, CACHE_ENABLED) busdp( | ||||
|       .clk, .reset, | ||||
|       .LSUBusHRDATA, .LSUBusAck, .LSUBusWrite, .LSUBusRead, .LSUBusSize, | ||||
|       .WordCount, .LSUBusWriteCrit, | ||||
| @ -224,7 +225,7 @@ module lsu ( | ||||
|       .y(WordOffsetAddr)); // *** can reduce width of mux. only need the offset.
 | ||||
|      | ||||
| 
 | ||||
|     if(`DMEM == `MEM_CACHE) begin : dcache | ||||
|     if(CACHE_ENABLED) begin : dcache | ||||
|       logic [1:0] RW, Atomic; | ||||
|       assign RW = CacheableM ? LSURWM : 2'b00;        // AND gate
 | ||||
|       assign Atomic = CacheableM ? LSUAtomicM : 2'b00; // AND gate
 | ||||
|  | ||||
| @ -78,13 +78,12 @@ module lsuvirtmem( | ||||
|   logic                       ITLBMissOrDAFaultF, ITLBMissOrDAFaultNoTrapF; | ||||
|   logic                       DTLBMissOrDAFaultM, DTLBMissOrDAFaultNoTrapM;   | ||||
| 
 | ||||
|   assign AnyCPUReqM = (|MemRWM) | (|AtomicM); | ||||
|   assign ITLBMissOrDAFaultF = ITLBMissF | (`HPTW_WRITES_SUPPORTED & InstrDAPageFaultF); | ||||
|   assign DTLBMissOrDAFaultM = DTLBMissM | (`HPTW_WRITES_SUPPORTED & DataDAPageFaultM);   | ||||
|   assign ITLBMissOrDAFaultNoTrapF = ITLBMissOrDAFaultF & ~TrapM; | ||||
|   assign DTLBMissOrDAFaultNoTrapM = DTLBMissOrDAFaultM & ~TrapM; | ||||
|   interlockfsm interlockfsm ( | ||||
|     .clk, .reset, .AnyCPUReqM, .ITLBMissOrDAFaultF, .ITLBWriteF, | ||||
|     .clk, .reset, .MemRWM, .AtomicM, .ITLBMissOrDAFaultF, .ITLBWriteF, | ||||
|     .DTLBMissOrDAFaultM, .DTLBWriteM, .TrapM, .DCacheStallM, | ||||
|     .InterlockStall, .SelReplayCPURequest, .SelHPTW, .IgnoreRequestTLB, .IgnoreRequestTrapM); | ||||
|   hptw hptw( // *** remove logic from (), mention this in style guide CH3
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user