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
						9b1f85d353
					
				
							
								
								
									
										71
									
								
								pipelined/src/generic/flop/bram1p1rw.sv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								pipelined/src/generic/flop/bram1p1rw.sv
									
									
									
									
									
										Normal file
									
								
							| @ -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<NUM_COL;i=i+1) begin | ||||
| 		if(we[i]) begin | ||||
| 		  RAM[addr][i*COL_WIDTH +: COL_WIDTH] <= din[i*COL_WIDTH +:COL_WIDTH]; | ||||
| 		end | ||||
| 	  end | ||||
| 	end | ||||
|   end | ||||
| endmodule // bytewrite_tdp_ram_rf
 | ||||
							
								
								
									
										82
									
								
								pipelined/src/generic/flop/bram2p1r1w.sv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								pipelined/src/generic/flop/bram2p1r1w.sv
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,82 @@ | ||||
| ///////////////////////////////////////////
 | ||||
| // 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 bram2p1r1w | ||||
|   #( | ||||
| 	//--------------------------------------------------------------------------
 | ||||
| 	parameter NUM_COL = 8, | ||||
| 	parameter COL_WIDTH = 8, | ||||
| 	parameter ADDR_WIDTH = 10, | ||||
|     parameter PRELOAD_ENABLED = 0, | ||||
|     parameter PRELOAD_FILE = "bootrom.txt", | ||||
| 	// 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 | ||||
|     if(PRELOAD_ENABLED) | ||||
| 	  $readmemh(PRELOAD_FILE, 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<NUM_COL;i=i+1) begin | ||||
| 		if(weB[i]) begin | ||||
| 		  RAM[addrB][i*COL_WIDTH +: COL_WIDTH] <= dinB[i*COL_WIDTH +:COL_WIDTH]; | ||||
| 		end | ||||
| 	  end | ||||
| 	end | ||||
|   end | ||||
| endmodule // bytewrite_tdp_ram_rf
 | ||||
| @ -39,6 +39,14 @@ module simpleram #(parameter BASE=0, RANGE = 65535) ( | ||||
|   output logic [`XLEN-1:0] rd | ||||
| ); | ||||
| 
 | ||||
|   localparam ADDR_WDITH = $clog2(RANGE/8); | ||||
|   localparam OFFSET = $clog2(`XLEN/8); | ||||
| 
 | ||||
| 
 | ||||
|   bram1p1rw #(`XLEN/8, 8, ADDR_WDITH)  | ||||
|   memory(.clk, .ena(we), .we(ByteMask), .addr(a[ADDR_WDITH+OFFSET-1:OFFSET]), .dout(rd), .din(wd)); | ||||
|    | ||||
| /* -----\/----- EXCLUDED -----\/----- | ||||
|   logic [`XLEN-1:0] RAM[BASE>>(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 | ||||
| 
 | ||||
|  | ||||
| @ -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), | ||||
|  | ||||
| @ -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), | ||||
|  | ||||
| @ -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,12 +71,14 @@ 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                       SelHPTWAdr; | ||||
|    | ||||
|   assign ITLBMissOrDAFaultF = ITLBMissF | (`HPTW_WRITES_SUPPORTED & InstrDAPageFaultF); | ||||
|   assign DTLBMissOrDAFaultM = DTLBMissM | (`HPTW_WRITES_SUPPORTED & DataDAPageFaultM);   | ||||
| @ -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; | ||||
|  | ||||
| @ -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]; | ||||
|    | ||||
|    | ||||
|   ///////////////////////////////////////////
 | ||||
|  | ||||
| @ -43,78 +43,22 @@ module ram #(parameter BASE=0, RANGE = 65535) ( | ||||
|   output logic             HRESPRam, HREADYRam | ||||
| ); | ||||
| 
 | ||||
|   localparam MemStartAddr = BASE>>(1+`XLEN/32); | ||||
|   localparam MemEndAddr = (RANGE+BASE)>>1+(`XLEN/32); | ||||
|    | ||||
|   logic [`XLEN-1:0] RAM[BASE>>(1+`XLEN/32):(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/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)); | ||||
|   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_ff @(posedge HCLK, negedge HRESETn)  | ||||
|   always @(posedge HCLK, negedge HRESETn)  | ||||
|     if (~HRESETn) begin | ||||
|       busycount <= 0; | ||||
|       HREADYRam <= #1 0; | ||||
| @ -132,46 +76,25 @@ module ram #(parameter BASE=0, RANGE = 65535) ( | ||||
|     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 | ||||
|    | ||||
|  | ||||
| @ -368,14 +368,14 @@ 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"); | ||||
| @ -383,7 +383,7 @@ module testbench; | ||||
|       InstrCountW = '0; | ||||
|       AttemptedInstructionCount = '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; | ||||
| @ -791,9 +791,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 | ||||
|  | ||||
| @ -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
 | ||||
| @ -178,7 +179,7 @@ logic [3:0] dummy; | ||||
|       // the design.
 | ||||
|       if (TEST == "coremark")  | ||||
|         for (i=MemStartAddr; i<MemEndAddr; i = i+1)  | ||||
|           dut.uncore.ram.ram.RAM[i] = 64'h0;  | ||||
|           dut.uncore.ram.ram.memory.RAM[i] = 64'h0;  | ||||
| 
 | ||||
|       // read test vectors into memory
 | ||||
|       pathname = tvpaths[tests[0].atoi()]; | ||||
| @ -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.RAM); | ||||
|       else              $readmemh(memfilename, dut.uncore.ram.ram.RAM); | ||||
|       if (`DMEM == `MEM_TIM) $readmemh(memfilename, dut.core.lsu.dtim.dtim.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.memory.RAM); | ||||
| 
 | ||||
|       ProgramAddrMapFile = {pathname, tests[test], ".elf.objdump.addr"}; | ||||
|       ProgramLabelMapFile = {pathname, tests[test], ".elf.objdump.lab"}; | ||||
| @ -243,14 +244,15 @@ 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.RAM[testadr+i]; | ||||
|           else                   sig = dut.uncore.ram.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 & | ||||
|           //if (signature[i] !== dut.core.lsu.dtim.ram.RAM[testadr+i] &
 | ||||
|           //if (signature[i] !== dut.core.lsu.dtim.ram.memory.RAM[testadr+i] &
 | ||||
| 	      (signature[i] !== DCacheFlushFSM.ShadowRAM[testadr+i])) begin  // ***i+1?
 | ||||
|             if ((signature[i] !== '0 | signature[i+4] !== 'x)) begin | ||||
| //            if (signature[i+4] !== 'bx | (signature[i] !== 32'hFFFFFFFF & signature[i] !== 32'h00000000)) begin
 | ||||
| @ -260,7 +262,7 @@ logic [3:0] dummy; | ||||
|               errors = errors+1; | ||||
|               $display("  Error on test %s result %d: adr = %h sim (D$) %h sim (DMEM) = %h, signature = %h",  | ||||
|                     tests[test], i, (testadr+i)*(`XLEN/8), DCacheFlushFSM.ShadowRAM[testadr+i], sig, signature[i]); | ||||
|                     //   tests[test], i, (testadr+i)*(`XLEN/8), DCacheFlushFSM.ShadowRAM[testadr+i], dut.core.lsu.dtim.ram.RAM[testadr+i], signature[i]);
 | ||||
|                     //   tests[test], i, (testadr+i)*(`XLEN/8), DCacheFlushFSM.ShadowRAM[testadr+i], dut.core.lsu.dtim.ram.memory.RAM[testadr+i], signature[i]);
 | ||||
|               $stop;//***debug
 | ||||
|             end | ||||
|           end | ||||
| @ -283,10 +285,10 @@ logic [3:0] dummy; | ||||
|         else begin | ||||
|             //pathname = tvpaths[tests[0]];
 | ||||
|             memfilename = {pathname, tests[test], ".elf.memfile"}; | ||||
|             //$readmemh(memfilename, dut.uncore.ram.ram.RAM);
 | ||||
|             if (`IMEM == `MEM_TIM) $readmemh(memfilename, dut.core.ifu.irom.irom.ram.RAM); | ||||
|             else                   $readmemh(memfilename, dut.uncore.ram.ram.RAM); | ||||
|             if (`DMEM == `MEM_TIM) $readmemh(memfilename, dut.core.lsu.dtim.dtim.ram.RAM); | ||||
|             //$readmemh(memfilename, dut.uncore.ram.ram.memory.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.memory.RAM); | ||||
| 
 | ||||
|             ProgramAddrMapFile = {pathname, tests[test], ".elf.objdump.addr"}; | ||||
|             ProgramLabelMapFile = {pathname, tests[test], ".elf.objdump.lab"}; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user