From a357f2a0e7681dd4ef23efcdd16c2265ba88deaa Mon Sep 17 00:00:00 2001 From: David Harris Date: Fri, 29 Jan 2021 23:43:48 -0500 Subject: [PATCH] Connected AHB bus to Uncore --- wally-pipelined/config/rv32ic/wally-config.vh | 16 +- wally-pipelined/config/rv64ic/wally-config.vh | 16 +- wally-pipelined/regression/wally-pipelined.do | 4 +- wally-pipelined/src/adrdec.sv | 14 +- wally-pipelined/src/ahblite.sv | 12 +- wally-pipelined/src/clint.sv | 59 +++--- wally-pipelined/src/csrm.sv | 2 +- wally-pipelined/src/dtim.sv | 58 +++--- wally-pipelined/src/gpio.sv | 60 +++--- wally-pipelined/src/subword.sv | 188 ------------------ wally-pipelined/src/subwordread.sv | 115 +++++++++++ wally-pipelined/src/subwordwrite.sv | 110 ++++++++++ wally-pipelined/src/uart.sv | 50 ++--- wally-pipelined/src/uncore.sv | 92 +++++---- wally-pipelined/src/wallypipelinedhart.sv | 18 +- wally-pipelined/src/wallypipelinedsoc.sv | 20 +- .../testbench/testbench-imperas.sv | 10 +- 17 files changed, 457 insertions(+), 387 deletions(-) delete mode 100644 wally-pipelined/src/subword.sv create mode 100644 wally-pipelined/src/subwordread.sv create mode 100644 wally-pipelined/src/subwordwrite.sv diff --git a/wally-pipelined/config/rv32ic/wally-config.vh b/wally-pipelined/config/rv32ic/wally-config.vh index 70bd4a0a5..b264ebca5 100644 --- a/wally-pipelined/config/rv32ic/wally-config.vh +++ b/wally-pipelined/config/rv32ic/wally-config.vh @@ -61,14 +61,14 @@ // Peripheral memory space extends from BASE to BASE+RANGE // Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits -`define TIMBASE 64'h0000000080000000 -`define TIMRANGE 64'h000000000007FFFF -`define CLINTBASE 64'h0000000002000000 -`define CLINTRANGE 64'h000000000000FFFF -`define GPIOBASE 64'h0000000010012000 -`define GPIORANGE 64'h00000000000000FF -`define UARTBASE 64'h0000000010000000 -`define UARTRANGE 64'h0000000000000007 +`define TIMBASE 32'h80000000 +`define TIMRANGE 32'h0007FFFF +`define CLINTBASE 32'h02000000 +`define CLINTRANGE 32'h0000FFFF +`define GPIOBASE 32'h10012000 +`define GPIORANGE 32'h000000FF +`define UARTBASE 32'h10000000 +`define UARTRANGE 32'h00000007 // Bus Interface width `define AHBW 32 diff --git a/wally-pipelined/config/rv64ic/wally-config.vh b/wally-pipelined/config/rv64ic/wally-config.vh index 871706352..eb340ddc2 100644 --- a/wally-pipelined/config/rv64ic/wally-config.vh +++ b/wally-pipelined/config/rv64ic/wally-config.vh @@ -65,14 +65,14 @@ // Peripheral memory space extends from BASE to BASE+RANGE // Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits -`define TIMBASE 64'h0000000080000000 -`define TIMRANGE 64'h000000000007FFFF -`define CLINTBASE 64'h0000000002000000 -`define CLINTRANGE 64'h000000000000FFFF -`define GPIOBASE 64'h0000000010012000 -`define GPIORANGE 64'h00000000000000FF -`define UARTBASE 64'h0000000010000000 -`define UARTRANGE 64'h0000000000000007 +`define TIMBASE 32'h80000000 +`define TIMRANGE 32'h0007FFFF +`define CLINTBASE 32'h02000000 +`define CLINTRANGE 32'h0000FFFF +`define GPIOBASE 32'h10012000 +`define GPIORANGE 32'h000000FF +`define UARTBASE 32'h10000000 +`define UARTRANGE 32'h00000007 // Test modes diff --git a/wally-pipelined/regression/wally-pipelined.do b/wally-pipelined/regression/wally-pipelined.do index a7c63cc8c..c3d9ed19d 100644 --- a/wally-pipelined/regression/wally-pipelined.do +++ b/wally-pipelined/regression/wally-pipelined.do @@ -64,8 +64,8 @@ add wave -divider #add wave -hex /testbench/dut/hart/ifu/InstrM add wave /testbench/InstrMName add wave /testbench/dut/uncore/dtim/memwrite -add wave -hex /testbench/dut/uncore/AdrM -add wave -hex /testbench/dut/uncore/WriteDataM +add wave -hex /testbench/dut/uncore/HADDR +add wave -hex /testbench/dut/uncore/HWDATA add wave -divider add wave -hex /testbench/dut/hart/ifu/PCW add wave /testbench/InstrWName diff --git a/wally-pipelined/src/adrdec.sv b/wally-pipelined/src/adrdec.sv index 86ab14606..7e4423ec1 100644 --- a/wally-pipelined/src/adrdec.sv +++ b/wally-pipelined/src/adrdec.sv @@ -26,19 +26,19 @@ `include "wally-config.vh" module adrdec ( - input logic [`XLEN-1:0] AdrM, - input logic [`XLEN-1:0] Base, Range, - output logic En + input logic [31:0] HADDR, + input logic [31:0] Base, Range, + output logic HSEL ); - logic [`XLEN-1:0] match; + logic [31:0] match; // determine if an address is in a range starting at the base // for example, if Base = 0x04002000 and range = 0x00000FFF, - // then anything address between 0x04002000 and 0x04002FFF should match (En=1) + // then anything address between 0x04002000 and 0x04002FFF should match (HSEL=1) - assign match = (AdrM ~^ Base) | Range; - assign En = &match; + assign match = (HADDR ~^ Base) | Range; + assign HSEL = &match; endmodule diff --git a/wally-pipelined/src/ahblite.sv b/wally-pipelined/src/ahblite.sv index e3bb69ded..f88bcb53e 100644 --- a/wally-pipelined/src/ahblite.sv +++ b/wally-pipelined/src/ahblite.sv @@ -32,6 +32,8 @@ module ahblite ( input logic clk, reset, + // Load control + input logic UnsignedLoadM, // Signals from Instruction Cache input logic [`XLEN-1:0] IPAdrD, input logic IReadD, @@ -60,6 +62,7 @@ module ahblite ( logic HCLK, HRESETn; logic GrantData; logic [2:0] ISize; + logic [`AHBW-1:0] HRDATAMasked; assign HCLK = clk; assign HRESETn = ~reset; @@ -77,7 +80,8 @@ module ahblite ( // drive bus outputs assign HADDR = GrantData ? DPAdrM[31:0] : IPAdrD[31:0]; - flop #(`XLEN) wdreg(HCLK, DWDataM, HWDATA); // delay HWDATA by 1 cycle per spec; *** assumes AHBW = XLEN + assign HWDATA = DWDataM; + //flop #(`XLEN) wdreg(HCLK, DWDataM, HWDATA); // delay HWDATA by 1 cycle per spec; *** assumes AHBW = XLEN assign HWRITE = DWriteM; // *** check no level to pulse conversion needed assign HSIZE = GrantData ? {1'b0, DSizeM} : ISize; assign HBURST = 3'b000; // Single burst only supported; consider generalizing for cache fillsfHPROT @@ -87,13 +91,15 @@ module ahblite ( // Route signals to Instruction and Data Caches // *** assumes AHBW = XLEN - assign IRData = HRDATA; + assign IRData = HRDATAMasked; assign IReady = HREADY & IReadD & ~GrantData; - assign DRData = HRDATA; + assign DRData = HRDATAMasked; assign DReady = HREADY & GrantData; // *** consider adding memory access faults based on HRESP being high // InstrAccessFaultF, DataAccessFaultM, + subwordread swr(.*); + endmodule diff --git a/wally-pipelined/src/clint.sv b/wally-pipelined/src/clint.sv index 5db89d7b1..2482e8293 100644 --- a/wally-pipelined/src/clint.sv +++ b/wally-pipelined/src/clint.sv @@ -27,12 +27,13 @@ `include "wally-config.vh" module clint ( - input logic clk, reset, - input logic [1:0] MemRWclintM, - input logic [15:0] AdrM, - input logic [`XLEN-1:0] MaskedWriteDataM, - output logic [`XLEN-1:0] RdCLINTM, - output logic TimerIntM, SwIntM); + input logic clk, reset, + input logic [1:0] MemRWclint, + input logic [15:0] HADDR, + input logic [`XLEN-1:0] HWDATA, + output logic [`XLEN-1:0] HREADCLINT, + output logic HRESPCLINT, HREADYCLINT, + output logic TimerIntM, SwIntM); logic [63:0] MTIMECMP, MTIME; logic MSIP; @@ -40,15 +41,17 @@ module clint ( logic [15:0] entry; logic memread, memwrite; - assign memread = MemRWclintM[1]; - assign memwrite = MemRWclintM[0]; + assign memread = MemRWclint[1]; + assign memwrite = MemRWclint[0]; + assign HRESPCLINT = 0; // OK + assign HREADYCLINT = 1; // Respond immediately // word aligned reads generate if (`XLEN==64) - assign #2 entry = {AdrM[15:3], 3'b000}; + assign #2 entry = {HADDR[15:3], 3'b000}; else - assign #2 entry = {AdrM[15:2], 2'b00}; + assign #2 entry = {HADDR[15:2], 2'b00}; endgenerate @@ -57,10 +60,10 @@ module clint ( if (`XLEN==64) begin always_comb begin case(entry) - 16'h0000: RdCLINTM = {63'b0, MSIP}; - 16'h4000: RdCLINTM = MTIMECMP; - 16'hBFF8: RdCLINTM = MTIME; - default: RdCLINTM = 0; + 16'h0000: HREADCLINT = {63'b0, MSIP}; + 16'h4000: HREADCLINT = MTIMECMP; + 16'hBFF8: HREADCLINT = MTIME; + default: HREADCLINT = 0; endcase end always_ff @(posedge clk or posedge reset) @@ -70,21 +73,21 @@ module clint ( MTIMECMP <= 0; // MTIMECMP is not reset end else if (memwrite) begin - if (entry == 16'h0000) MSIP <= MaskedWriteDataM[0]; - if (entry == 16'h4000) MTIMECMP <= MaskedWriteDataM; + if (entry == 16'h0000) MSIP <= HWDATA[0]; + if (entry == 16'h4000) MTIMECMP <= HWDATA; // MTIME Counter. Eventually change this to run off separate clock. Synchronization then needed - if (entry == 16'hBFF8) MTIME <= MaskedWriteDataM; + if (entry == 16'hBFF8) MTIME <= HWDATA; else MTIME <= MTIME + 1; end end else begin // 32-bit always_comb begin case(entry) - 16'h0000: RdCLINTM = {31'b0, MSIP}; - 16'h4000: RdCLINTM = MTIMECMP[31:0]; - 16'h4004: RdCLINTM = MTIMECMP[63:32]; - 16'hBFF8: RdCLINTM = MTIME[31:0]; - 16'hBFFC: RdCLINTM = MTIME[63:32]; - default: RdCLINTM = 0; + 16'h0000: HREADCLINT = {31'b0, MSIP}; + 16'h4000: HREADCLINT = MTIMECMP[31:0]; + 16'h4004: HREADCLINT = MTIMECMP[63:32]; + 16'hBFF8: HREADCLINT = MTIME[31:0]; + 16'hBFFC: HREADCLINT = MTIME[63:32]; + default: HREADCLINT = 0; endcase end always_ff @(posedge clk or posedge reset) @@ -94,12 +97,12 @@ module clint ( MTIMECMP <= 0; // MTIMECMP is not reset end else if (memwrite) begin - if (entry == 16'h0000) MSIP <= MaskedWriteDataM[0]; - if (entry == 16'h4000) MTIMECMP[31:0] <= MaskedWriteDataM; - if (entry == 16'h4004) MTIMECMP[63:32] <= MaskedWriteDataM; + if (entry == 16'h0000) MSIP <= HWDATA[0]; + if (entry == 16'h4000) MTIMECMP[31:0] <= HWDATA; + if (entry == 16'h4004) MTIMECMP[63:32] <= HWDATA; // MTIME Counter. Eventually change this to run off separate clock. Synchronization then needed - if (entry == 16'hBFF8) MTIME[31:0] <= MaskedWriteDataM; - else if (entry == 16'hBFFC) MTIME[63:32]<= MaskedWriteDataM; + if (entry == 16'hBFF8) MTIME[31:0] <= HWDATA; + else if (entry == 16'hBFFC) MTIME[63:32]<= HWDATA; else MTIME <= MTIME + 1; end end diff --git a/wally-pipelined/src/csrm.sv b/wally-pipelined/src/csrm.sv index e86eb15a7..4de18626b 100644 --- a/wally-pipelined/src/csrm.sv +++ b/wally-pipelined/src/csrm.sv @@ -169,7 +169,7 @@ module csrm #(parameter PMPCFG0: CSRMReadValM = PMPCFG01_REGW[`XLEN-1:0]; PMPCFG1: CSRMReadValM = {{(`XLEN-32){1'b0}}, PMPCFG01_REGW[63:31]}; PMPCFG2: CSRMReadValM = PMPCFG23_REGW[`XLEN-1:0]; - PMPCFG3: CSRMReadValM = PMPCFG23_REGW[63:31]; + PMPCFG3: CSRMReadValM = {{(`XLEN-32){1'b0}}, PMPCFG23_REGW[63:31]}; PMPADDR0: CSRMReadValM = PMPADDR0_REGW; default: begin CSRMReadValM = 0; diff --git a/wally-pipelined/src/dtim.sv b/wally-pipelined/src/dtim.sv index 41cdad78e..93abad68b 100644 --- a/wally-pipelined/src/dtim.sv +++ b/wally-pipelined/src/dtim.sv @@ -27,28 +27,32 @@ module dtim ( input logic clk, - input logic [1:0] MemRWdtimM, + input logic [1:0] MemRWtim, // input logic [7:0] ByteMaskM, - input logic [18:0] AdrM, - input logic [`XLEN-1:0] MaskedWriteDataM, - output logic [`XLEN-1:0] RdTimM); + input logic [18:0] HADDR, + input logic [`XLEN-1:0] HWDATA, + output logic [`XLEN-1:0] HREADTim, + output logic HRESPTim, HREADYTim +); logic [`XLEN-1:0] RAM[0:65535]; logic [`XLEN-1:0] write; logic [15:0] entry; logic memread, memwrite; - assign memread = MemRWdtimM[1]; - assign memwrite = MemRWdtimM[0]; + assign memread = MemRWtim[1]; + assign memwrite = MemRWtim[0]; + assign HRESPTim = 0; // OK + assign HREADYTim= 1; // Respond immediately; *** extend this // word aligned reads generate if (`XLEN==64) - assign #2 entry = AdrM[18:3]; + assign #2 entry = HADDR[18:3]; else - assign #2 entry = AdrM[17:2]; + assign #2 entry = HADDR[17:2]; endgenerate - assign RdTimM = RAM[entry]; + assign HREADTim = RAM[entry]; // write each byte based on the byte mask // UInstantiate a byte-writable memory here if possible @@ -58,37 +62,37 @@ module dtim ( if (`XLEN==64) begin always_comb begin - write=RdTimM; - if (ByteMaskM[0]) write[7:0] = WriteDataM[7:0]; - if (ByteMaskM[1]) write[15:8] = WriteDataM[15:8]; - if (ByteMaskM[2]) write[23:16] = WriteDataM[23:16]; - if (ByteMaskM[3]) write[31:24] = WriteDataM[31:24]; - if (ByteMaskM[4]) write[39:32] = WriteDataM[39:32]; - if (ByteMaskM[5]) write[47:40] = WriteDataM[47:40]; - if (ByteMaskM[6]) write[55:48] = WriteDataM[55:48]; - if (ByteMaskM[7]) write[63:56] = WriteDataM[63:56]; + write=HREADTim; + if (ByteMaskM[0]) write[7:0] = HWDATA[7:0]; + if (ByteMaskM[1]) write[15:8] = HWDATA[15:8]; + if (ByteMaskM[2]) write[23:16] = HWDATA[23:16]; + if (ByteMaskM[3]) write[31:24] = HWDATA[31:24]; + if (ByteMaskM[4]) write[39:32] = HWDATA[39:32]; + if (ByteMaskM[5]) write[47:40] = HWDATA[47:40]; + if (ByteMaskM[6]) write[55:48] = HWDATA[55:48]; + if (ByteMaskM[7]) write[63:56] = HWDATA[63:56]; end always_ff @(posedge clk) - if (memwrite) RAM[AdrM[18:3]] <= write; + if (memwrite) RAM[HADDR[18:3]] <= write; end else begin // 32-bit always_comb begin - write=RdTimM; - if (ByteMaskM[0]) write[7:0] = WriteDataM[7:0]; - if (ByteMaskM[1]) write[15:8] = WriteDataM[15:8]; - if (ByteMaskM[2]) write[23:16] = WriteDataM[23:16]; - if (ByteMaskM[3]) write[31:24] = WriteDataM[31:24]; + write=HREADTim; + if (ByteMaskM[0]) write[7:0] = HWDATA[7:0]; + if (ByteMaskM[1]) write[15:8] = HWDATA[15:8]; + if (ByteMaskM[2]) write[23:16] = HWDATA[23:16]; + if (ByteMaskM[3]) write[31:24] = HWDATA[31:24]; end always_ff @(posedge clk) - if (memwrite) RAM[AdrM[17:2]] <= write; + if (memwrite) RAM[HADDR[17:2]] <= write; end endgenerate */ generate if (`XLEN == 64) begin always_ff @(posedge clk) - if (memwrite) RAM[AdrM[17:3]] <= MaskedWriteDataM; + if (memwrite) RAM[HADDR[17:3]] <= HWDATA; end else begin always_ff @(posedge clk) - if (memwrite) RAM[AdrM[17:2]] <= MaskedWriteDataM; + if (memwrite) RAM[HADDR[17:2]] <= HWDATA; end endgenerate endmodule diff --git a/wally-pipelined/src/gpio.sv b/wally-pipelined/src/gpio.sv index d2a027700..33a296388 100644 --- a/wally-pipelined/src/gpio.sv +++ b/wally-pipelined/src/gpio.sv @@ -28,29 +28,31 @@ `include "wally-config.vh" module gpio ( - input logic clk, reset, - input logic [1:0] MemRWgpioM, -// input logic [7:0] ByteMaskM, - input logic [7:0] AdrM, - input logic [`XLEN-1:0] MaskedWriteDataM, - output logic [`XLEN-1:0] RdGPIOM, - input logic [31:0] GPIOPinsIn, - output logic [31:0] GPIOPinsOut, GPIOPinsEn); + input logic clk, reset, + input logic [1:0] MemRWgpio, + input logic [7:0] HADDR, + input logic [`XLEN-1:0] HWDATA, + output logic [`XLEN-1:0] HREADGPIO, + output logic HRESPGPIO, HREADYGPIO, + input logic [31:0] GPIOPinsIn, + output logic [31:0] GPIOPinsOut, GPIOPinsEn); logic [31:0] INPUT_VAL, INPUT_EN, OUTPUT_EN, OUTPUT_VAL; logic [7:0] entry; logic memread, memwrite; - assign memread = MemRWgpioM[1]; - assign memwrite = MemRWgpioM[0]; + assign memread = MemRWgpio[1]; + assign memwrite = MemRWgpio[0]; + assign HRESPGPIO = 0; // OK + assign HREADYGPIO = 1; // Respond immediately // word aligned reads generate if (`XLEN==64) - assign #2 entry = {AdrM[7:3], 3'b000}; + assign #2 entry = {HADDR[7:3], 3'b000}; else - assign #2 entry = {AdrM[7:2], 2'b00}; + assign #2 entry = {HADDR[7:2], 2'b00}; endgenerate generate @@ -67,10 +69,10 @@ module gpio ( if (`XLEN==64) begin always_comb begin case(entry) - 8'h00: RdGPIOM = {INPUT_EN, INPUT_VAL}; - 8'h08: RdGPIOM = {OUTPUT_VAL, OUTPUT_EN}; - 8'h40: RdGPIOM = 0; // OUT_XOR reads as 0 - default: RdGPIOM = 0; + 8'h00: HREADGPIO = {INPUT_EN, INPUT_VAL}; + 8'h08: HREADGPIO = {OUTPUT_VAL, OUTPUT_EN}; + 8'h40: HREADGPIO = 0; // OUT_XOR reads as 0 + default: HREADGPIO = 0; endcase end always_ff @(posedge clk or posedge reset) @@ -79,19 +81,19 @@ module gpio ( OUTPUT_EN <= 0; OUTPUT_VAL <= 0; // spec indicates synchronous reset (software control) end else if (memwrite) begin - if (entry == 8'h00) INPUT_EN <= MaskedWriteDataM[63:32]; - if (entry == 8'h08) {OUTPUT_VAL, OUTPUT_EN} <= MaskedWriteDataM; - if (entry == 8'h40) OUTPUT_VAL <= OUTPUT_VAL ^ MaskedWriteDataM[31:0]; // OUT_XOR + if (entry == 8'h00) INPUT_EN <= HWDATA[63:32]; + if (entry == 8'h08) {OUTPUT_VAL, OUTPUT_EN} <= HWDATA; + if (entry == 8'h40) OUTPUT_VAL <= OUTPUT_VAL ^ HWDATA[31:0]; // OUT_XOR end end else begin // 32-bit always_comb begin case(entry) - 8'h00: RdGPIOM = INPUT_VAL; - 8'h04: RdGPIOM = INPUT_EN; - 8'h08: RdGPIOM = OUTPUT_EN; - 8'h0C: RdGPIOM = OUTPUT_VAL; - 8'h40: RdGPIOM = 0; // OUT_XOR reads as 0 - default: RdGPIOM = 0; + 8'h00: HREADGPIO = INPUT_VAL; + 8'h04: HREADGPIO = INPUT_EN; + 8'h08: HREADGPIO = OUTPUT_EN; + 8'h0C: HREADGPIO = OUTPUT_VAL; + 8'h40: HREADGPIO = 0; // OUT_XOR reads as 0 + default: HREADGPIO = 0; endcase end always_ff @(posedge clk or posedge reset) @@ -100,10 +102,10 @@ module gpio ( OUTPUT_EN <= 0; //OUTPUT_VAL <= 0;// spec indicates synchronous rset (software control) end else if (memwrite) begin - if (entry == 8'h04) INPUT_EN <= MaskedWriteDataM; - if (entry == 8'h08) OUTPUT_EN <= MaskedWriteDataM; - if (entry == 8'h0C) OUTPUT_VAL <= MaskedWriteDataM; - if (entry == 8'h40) OUTPUT_VAL <= OUTPUT_VAL ^ MaskedWriteDataM; // OUT_XOR + if (entry == 8'h04) INPUT_EN <= HWDATA; + if (entry == 8'h08) OUTPUT_EN <= HWDATA; + if (entry == 8'h0C) OUTPUT_VAL <= HWDATA; + if (entry == 8'h40) OUTPUT_VAL <= OUTPUT_VAL ^ HWDATA; // OUT_XOR end end endgenerate diff --git a/wally-pipelined/src/subword.sv b/wally-pipelined/src/subword.sv deleted file mode 100644 index 6b9a544a9..000000000 --- a/wally-pipelined/src/subword.sv +++ /dev/null @@ -1,188 +0,0 @@ -/////////////////////////////////////////// -// subword.sv -// -// Written: David_Harris@hmc.edu 9 January 2021 -// Modified: -// -// Purpose: Masking and muxing for subword accesses -// -// A component of the Wally configurable RISC-V project. -// -// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, -// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software -// is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -/////////////////////////////////////////// - -`include "wally-config.vh" - -module subword ( - input logic [1:0] MemRWM, - input logic [`XLEN-1:0] ReadDataUnmaskedM, - input logic [`XLEN-1:0] AdrM, - input logic [2:0] Funct3M, - output logic [`XLEN-1:0] ReadDataM, - input logic [`XLEN-1:0] WriteDataM, - output logic [`XLEN-1:0] MaskedWriteDataM -); - - logic [7:0] ByteM; // *** declare locally to generate as either 4 or 8 bits - logic [15:0] HalfwordM; - logic [`XLEN-1:0] WriteDataSubwordDuplicated; - logic [7:0] ByteMaskM; - - generate - if (`XLEN == 64) begin - // ByteMe mux - always_comb - case(AdrM[2:0]) - 3'b000: ByteM = ReadDataUnmaskedM[7:0]; - 3'b001: ByteM = ReadDataUnmaskedM[15:8]; - 3'b010: ByteM = ReadDataUnmaskedM[23:16]; - 3'b011: ByteM = ReadDataUnmaskedM[31:24]; - 3'b100: ByteM = ReadDataUnmaskedM[39:32]; - 3'b101: ByteM = ReadDataUnmaskedM[47:40]; - 3'b110: ByteM = ReadDataUnmaskedM[55:48]; - 3'b111: ByteM = ReadDataUnmaskedM[63:56]; - endcase - - // halfword mux - always_comb - case(AdrM[2:1]) - 2'b00: HalfwordM = ReadDataUnmaskedM[15:0]; - 2'b01: HalfwordM = ReadDataUnmaskedM[31:16]; - 2'b10: HalfwordM = ReadDataUnmaskedM[47:32]; - 2'b11: HalfwordM = ReadDataUnmaskedM[63:48]; - endcase - - logic [31:0] WordM; - - always_comb - case(AdrM[2]) - 1'b0: WordM = ReadDataUnmaskedM[31:0]; - 1'b1: WordM = ReadDataUnmaskedM[63:32]; - endcase - - // sign extension - always_comb - case(Funct3M) - 3'b000: ReadDataM = {{56{ByteM[7]}}, ByteM}; // lb - 3'b001: ReadDataM = {{48{HalfwordM[15]}}, HalfwordM[15:0]}; // lh - 3'b010: ReadDataM = {{32{WordM[31]}}, WordM[31:0]}; // lw - 3'b011: ReadDataM = ReadDataUnmaskedM; // ld - 3'b100: ReadDataM = {56'b0, ByteM[7:0]}; // lbu - 3'b101: ReadDataM = {48'b0, HalfwordM[15:0]}; // lhu - 3'b110: ReadDataM = {32'b0, WordM[31:0]}; // lwu - default: ReadDataM = 64'b0; - endcase - - // Memory control - - // Compute write mask - always_comb - case(Funct3M) - 3'b000: begin ByteMaskM = 8'b00000000; ByteMaskM[AdrM[2:0]] = 1; end // sb - 3'b001: case (AdrM[2:1]) - 2'b00: ByteMaskM = 8'b00000011; - 2'b01: ByteMaskM = 8'b00001100; - 2'b10: ByteMaskM = 8'b00110000; - 2'b11: ByteMaskM = 8'b11000000; - endcase - 3'b010: if (AdrM[2]) ByteMaskM = 8'b11110000; - else ByteMaskM = 8'b00001111; - 3'b011: ByteMaskM = 8'b11111111; - default: ByteMaskM = 8'b00000000; - endcase - - // Handle subword writes - always_comb - case(Funct3M) - 3'b000: WriteDataSubwordDuplicated = {8{WriteDataM[7:0]}}; // sb - 3'b001: WriteDataSubwordDuplicated = {4{WriteDataM[15:0]}}; // sh - 3'b010: WriteDataSubwordDuplicated = {2{WriteDataM[31:0]}}; // sw - 3'b011: WriteDataSubwordDuplicated = WriteDataM; // sw - default: WriteDataSubwordDuplicated = 64'b0; - endcase - - always_comb begin - MaskedWriteDataM=ReadDataUnmaskedM; - if (ByteMaskM[0]) MaskedWriteDataM[7:0] = WriteDataSubwordDuplicated[7:0]; - if (ByteMaskM[1]) MaskedWriteDataM[15:8] = WriteDataSubwordDuplicated[15:8]; - if (ByteMaskM[2]) MaskedWriteDataM[23:16] = WriteDataSubwordDuplicated[23:16]; - if (ByteMaskM[3]) MaskedWriteDataM[31:24] = WriteDataSubwordDuplicated[31:24]; - if (ByteMaskM[4]) MaskedWriteDataM[39:32] = WriteDataSubwordDuplicated[39:32]; - if (ByteMaskM[5]) MaskedWriteDataM[47:40] = WriteDataSubwordDuplicated[47:40]; - if (ByteMaskM[6]) MaskedWriteDataM[55:48] = WriteDataSubwordDuplicated[55:48]; - if (ByteMaskM[7]) MaskedWriteDataM[63:56] = WriteDataSubwordDuplicated[63:56]; - end - - end else begin // 32-bit - // byte mux - always_comb - case(AdrM[1:0]) - 2'b00: ByteM = ReadDataUnmaskedM[7:0]; - 2'b01: ByteM = ReadDataUnmaskedM[15:8]; - 2'b10: ByteM = ReadDataUnmaskedM[23:16]; - 2'b11: ByteM = ReadDataUnmaskedM[31:24]; - endcase - - // halfword mux - always_comb - case(AdrM[1]) - 1'b0: HalfwordM = ReadDataUnmaskedM[15:0]; - 1'b1: HalfwordM = ReadDataUnmaskedM[31:16]; - endcase - - // sign extension - always_comb - case(Funct3M) - 3'b000: ReadDataM = {{24{ByteM[7]}}, ByteM}; // lb - 3'b001: ReadDataM = {{16{HalfwordM[15]}}, HalfwordM[15:0]}; // lh - 3'b010: ReadDataM = ReadDataUnmaskedM; // lw - 3'b100: ReadDataM = {24'b0, ByteM[7:0]}; // lbu - 3'b101: ReadDataM = {16'b0, HalfwordM[15:0]}; // lhu - default: ReadDataM = 32'b0; - endcase - - // Memory control - - // Compute write mask - always_comb - case(Funct3M) - 3'b000: begin ByteMaskM = 8'b0000; ByteMaskM[{1'b0, AdrM[1:0]}] = 1; end // sb - 3'b001: if (AdrM[1]) ByteMaskM = 8'b1100; - else ByteMaskM = 8'b0011; - 3'b010: ByteMaskM = 8'b1111; - default: ByteMaskM = 8'b0000; - endcase - - // Handle subword writes - always_comb - case(Funct3M) - 3'b000: WriteDataSubwordDuplicated = {4{WriteDataM[7:0]}}; // sb - 3'b001: WriteDataSubwordDuplicated = {2{WriteDataM[15:0]}}; // sh - 3'b010: WriteDataSubwordDuplicated = WriteDataM; // sw - default: WriteDataSubwordDuplicated = 32'b0; - endcase - - always_comb begin - MaskedWriteDataM=ReadDataUnmaskedM; - if (ByteMaskM[0]) MaskedWriteDataM[7:0] = WriteDataSubwordDuplicated[7:0]; - if (ByteMaskM[1]) MaskedWriteDataM[15:8] = WriteDataSubwordDuplicated[15:8]; - if (ByteMaskM[2]) MaskedWriteDataM[23:16] = WriteDataSubwordDuplicated[23:16]; - if (ByteMaskM[3]) MaskedWriteDataM[31:24] = WriteDataSubwordDuplicated[31:24]; - end - - end - endgenerate - -endmodule diff --git a/wally-pipelined/src/subwordread.sv b/wally-pipelined/src/subwordread.sv new file mode 100644 index 000000000..4bf3d744a --- /dev/null +++ b/wally-pipelined/src/subwordread.sv @@ -0,0 +1,115 @@ +/////////////////////////////////////////// +// subwordread.sv +// +// Written: David_Harris@hmc.edu 9 January 2021 +// Modified: +// +// Purpose: Extract subwords and sign extend for reads +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +/////////////////////////////////////////// + +`include "wally-config.vh" + +module subwordread ( +// input logic [1:0] MemRWM, + input logic [`XLEN-1:0] HRDATA, + input logic [31:0] HADDR, + input logic UnsignedLoadM, + input logic [2:0] HSIZE, + output logic [`XLEN-1:0] HRDATAMasked +// input logic [`XLEN-1:0] HWDATA, +// output logic [`XLEN-1:0] HWDATA +); + + logic [7:0] ByteM; // *** declare locally to generate as either 4 or 8 bits + logic [15:0] HalfwordM; + + generate + if (`XLEN == 64) begin + // ByteMe mux + always_comb + case(HADDR[2:0]) + 3'b000: ByteM = HRDATA[7:0]; + 3'b001: ByteM = HRDATA[15:8]; + 3'b010: ByteM = HRDATA[23:16]; + 3'b011: ByteM = HRDATA[31:24]; + 3'b100: ByteM = HRDATA[39:32]; + 3'b101: ByteM = HRDATA[47:40]; + 3'b110: ByteM = HRDATA[55:48]; + 3'b111: ByteM = HRDATA[63:56]; + endcase + + // halfword mux + always_comb + case(HADDR[2:1]) + 2'b00: HalfwordM = HRDATA[15:0]; + 2'b01: HalfwordM = HRDATA[31:16]; + 2'b10: HalfwordM = HRDATA[47:32]; + 2'b11: HalfwordM = HRDATA[63:48]; + endcase + + logic [31:0] WordM; + + always_comb + case(HADDR[2]) + 1'b0: WordM = HRDATA[31:0]; + 1'b1: WordM = HRDATA[63:32]; + endcase + + // sign extension + always_comb + case({UnsignedLoadM, HSIZE[1:0]}) + 3'b000: HRDATAMasked = {{56{ByteM[7]}}, ByteM}; // lb + 3'b001: HRDATAMasked = {{48{HalfwordM[15]}}, HalfwordM[15:0]}; // lh + 3'b010: HRDATAMasked = {{32{WordM[31]}}, WordM[31:0]}; // lw + 3'b011: HRDATAMasked = HRDATA; // ld + 3'b100: HRDATAMasked = {56'b0, ByteM[7:0]}; // lbu + 3'b101: HRDATAMasked = {48'b0, HalfwordM[15:0]}; // lhu + 3'b110: HRDATAMasked = {32'b0, WordM[31:0]}; // lwu + default: HRDATAMasked = HRDATA; // Shouldn't happen + endcase + end else begin // 32-bit + // byte mux + always_comb + case(HADDR[1:0]) + 2'b00: ByteM = HRDATA[7:0]; + 2'b01: ByteM = HRDATA[15:8]; + 2'b10: ByteM = HRDATA[23:16]; + 2'b11: ByteM = HRDATA[31:24]; + endcase + + // halfword mux + always_comb + case(HADDR[1]) + 1'b0: HalfwordM = HRDATA[15:0]; + 1'b1: HalfwordM = HRDATA[31:16]; + endcase + + // sign extension + always_comb + case({UnsignedLoadM, HSIZE[1:0]}) + 3'b000: HRDATAMasked = {{24{ByteM[7]}}, ByteM}; // lb + 3'b001: HRDATAMasked = {{16{HalfwordM[15]}}, HalfwordM[15:0]}; // lh + 3'b010: HRDATAMasked = HRDATA; // lw + 3'b100: HRDATAMasked = {24'b0, ByteM[7:0]}; // lbu + 3'b101: HRDATAMasked = {16'b0, HalfwordM[15:0]}; // lhu + default: HRDATAMasked = HRDATA; + endcase + end + endgenerate +endmodule diff --git a/wally-pipelined/src/subwordwrite.sv b/wally-pipelined/src/subwordwrite.sv new file mode 100644 index 000000000..68c2b0e47 --- /dev/null +++ b/wally-pipelined/src/subwordwrite.sv @@ -0,0 +1,110 @@ +/////////////////////////////////////////// +// subwordwrite.sv +// +// Written: David_Harris@hmc.edu 9 January 2021 +// Modified: +// +// Purpose: Masking and muxing for subword writes +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +/////////////////////////////////////////// + +`include "wally-config.vh" + +module subwordwrite ( + input logic [`XLEN-1:0] HRDATA, + input logic [31:0] HADDR, + input logic [2:0] HSIZE, + input logic [`XLEN-1:0] HWDATAIN, + output logic [`XLEN-1:0] HWDATA +); + + logic [7:0] ByteM; // *** declare locally to generate as either 4 or 8 bits + logic [15:0] HalfwordM; + logic [`XLEN-1:0] WriteDataSubwordDuplicated; + logic [7:0] ByteMaskM; + + generate + if (`XLEN == 64) begin + // Compute write mask + always_comb + case(HSIZE[1:0]) + 2'b00: begin ByteMaskM = 8'b00000000; ByteMaskM[HADDR[2:0]] = 1; end // sb + 2'b01: case (HADDR[2:1]) + 2'b00: ByteMaskM = 8'b00000011; + 2'b01: ByteMaskM = 8'b00001100; + 2'b10: ByteMaskM = 8'b00110000; + 2'b11: ByteMaskM = 8'b11000000; + endcase + 2'b10: if (HADDR[2]) ByteMaskM = 8'b11110000; + else ByteMaskM = 8'b00001111; + 2'b11: ByteMaskM = 8'b11111111; + endcase + + // Handle subword writes + always_comb + case(HSIZE[1:0]) + 2'b00: WriteDataSubwordDuplicated = {8{HWDATAIN[7:0]}}; // sb + 2'b01: WriteDataSubwordDuplicated = {4{HWDATAIN[15:0]}}; // sh + 2'b10: WriteDataSubwordDuplicated = {2{HWDATAIN[31:0]}}; // sw + 2'b11: WriteDataSubwordDuplicated = HWDATAIN; // sw + endcase + + always_comb begin + HWDATA=HRDATA; + if (ByteMaskM[0]) HWDATA[7:0] = WriteDataSubwordDuplicated[7:0]; + if (ByteMaskM[1]) HWDATA[15:8] = WriteDataSubwordDuplicated[15:8]; + if (ByteMaskM[2]) HWDATA[23:16] = WriteDataSubwordDuplicated[23:16]; + if (ByteMaskM[3]) HWDATA[31:24] = WriteDataSubwordDuplicated[31:24]; + if (ByteMaskM[4]) HWDATA[39:32] = WriteDataSubwordDuplicated[39:32]; + if (ByteMaskM[5]) HWDATA[47:40] = WriteDataSubwordDuplicated[47:40]; + if (ByteMaskM[6]) HWDATA[55:48] = WriteDataSubwordDuplicated[55:48]; + if (ByteMaskM[7]) HWDATA[63:56] = WriteDataSubwordDuplicated[63:56]; + end + + end else begin // 32-bit + // Compute write mask + always_comb + case(HSIZE[1:0]) + 2'b00: begin ByteMaskM = 8'b0000; ByteMaskM[{1'b0, HADDR[1:0]}] = 1; end // sb + 2'b01: if (HADDR[1]) ByteMaskM = 8'b1100; + else ByteMaskM = 8'b0011; + 2'b10: ByteMaskM = 8'b1111; + default: ByteMaskM = 8'b111; // shouldn't happen + endcase + + // Handle subword writes + always_comb + case(HSIZE[1:0]) + 2'b00: WriteDataSubwordDuplicated = {4{HWDATAIN[7:0]}}; // sb + 2'b01: WriteDataSubwordDuplicated = {2{HWDATAIN[15:0]}}; // sh + 2'b10: WriteDataSubwordDuplicated = HWDATAIN; // sw + default: WriteDataSubwordDuplicated = HWDATAIN; // shouldn't happen + endcase + + always_comb begin + HWDATA=HRDATA; + if (ByteMaskM[0]) HWDATA[7:0] = WriteDataSubwordDuplicated[7:0]; + if (ByteMaskM[1]) HWDATA[15:8] = WriteDataSubwordDuplicated[15:8]; + if (ByteMaskM[2]) HWDATA[23:16] = WriteDataSubwordDuplicated[23:16]; + if (ByteMaskM[3]) HWDATA[31:24] = WriteDataSubwordDuplicated[31:24]; + end + + end + endgenerate + +endmodule diff --git a/wally-pipelined/src/uart.sv b/wally-pipelined/src/uart.sv index 2d792834a..b19d938cf 100644 --- a/wally-pipelined/src/uart.sv +++ b/wally-pipelined/src/uart.sv @@ -29,11 +29,11 @@ module uart ( input logic clk, reset, - input logic [1:0] MemRWuartM, -// input logic [7:0] ByteMaskM, - input logic [`XLEN-1:0] AdrM, - input logic [`XLEN-1:0] MaskedWriteDataM, - output logic [`XLEN-1:0] RdUARTM, + input logic [1:0] MemRWuart, + input logic [2:0] HADDR, + input logic [`XLEN-1:0] HWDATA, + output logic [`XLEN-1:0] HREADUART, + output logic HRESPUART, HREADYUART, input logic SIN, DSRb, DCDb, CTSb, RIb, // from E1A driver from RS232 interface output logic SOUT, RTSb, DTRb, // to E1A driver to RS232 interface output logic OUT1b, OUT2b, INTR, TXRDYb, RXRDYb); // to CPU @@ -44,33 +44,35 @@ module uart ( logic [7:0] Din, Dout; // rename processor interface signals to match PC16550D and provide one-byte interface - assign MEMRb = ~MemRWuartM[1]; - assign MEMWb = ~MemRWuartM[0]; - assign A = AdrM[2:0]; + assign MEMRb = ~MemRWuart[1]; + assign MEMWb = ~MemRWuart[0]; + assign A = HADDR[2:0]; + assign HRESPUART = 0; // OK + assign HREADYUART = 1; // Respond immediately generate if (`XLEN == 64) begin always_comb begin - RdUARTM = {Dout, Dout, Dout, Dout, Dout, Dout, Dout, Dout}; - case (AdrM[2:0]) - 3'b000: Din = MaskedWriteDataM[7:0]; - 3'b001: Din = MaskedWriteDataM[15:8]; - 3'b010: Din = MaskedWriteDataM[23:16]; - 3'b011: Din = MaskedWriteDataM[31:24]; - 3'b100: Din = MaskedWriteDataM[39:32]; - 3'b101: Din = MaskedWriteDataM[47:40]; - 3'b110: Din = MaskedWriteDataM[55:48]; - 3'b111: Din = MaskedWriteDataM[63:56]; + HREADUART = {Dout, Dout, Dout, Dout, Dout, Dout, Dout, Dout}; + case (HADDR) + 3'b000: Din = HWDATA[7:0]; + 3'b001: Din = HWDATA[15:8]; + 3'b010: Din = HWDATA[23:16]; + 3'b011: Din = HWDATA[31:24]; + 3'b100: Din = HWDATA[39:32]; + 3'b101: Din = HWDATA[47:40]; + 3'b110: Din = HWDATA[55:48]; + 3'b111: Din = HWDATA[63:56]; endcase end end else begin // 32-bit always_comb begin - RdUARTM = {Dout, Dout, Dout, Dout}; - case (AdrM[1:0]) - 2'b00: Din = MaskedWriteDataM[7:0]; - 2'b01: Din = MaskedWriteDataM[15:8]; - 2'b10: Din = MaskedWriteDataM[23:16]; - 2'b11: Din = MaskedWriteDataM[31:24]; + HREADUART = {Dout, Dout, Dout, Dout}; + case (HADDR[1:0]) + 2'b00: Din = HWDATA[7:0]; + 2'b01: Din = HWDATA[15:8]; + 2'b10: Din = HWDATA[23:16]; + 2'b11: Din = HWDATA[31:24]; endcase end end diff --git a/wally-pipelined/src/uncore.sv b/wally-pipelined/src/uncore.sv index 543716854..a61870b21 100644 --- a/wally-pipelined/src/uncore.sv +++ b/wally-pipelined/src/uncore.sv @@ -30,11 +30,20 @@ // *** and use memread signal to reduce power when reads aren't needed module uncore ( input logic clk, reset, + // AHB Bus Interface + input logic [31:0] HADDR, + input logic [`AHBW-1:0] HWDATAIN, + input logic HWRITE, + input logic [2:0] HSIZE, + input logic [2:0] HBURST, + input logic [3:0] HPROT, + input logic [1:0] HTRANS, + input logic HMASTLOCK, + input logic [`AHBW-1:0] HRDATAEXT, + input logic HREADYEXT, HRESPEXT, + output logic [`AHBW-1:0] HRDATA, + output logic HREADY, HRESP, // bus interface - input logic [1:0] MemRWM, - input logic [`XLEN-1:0] AdrM, WriteDataM, - input logic [2:0] Funct3M, - output logic [`XLEN-1:0] ReadDataM, output logic DataAccessFaultM, // peripheral pins output logic TimerIntM, SwIntM, @@ -44,56 +53,53 @@ module uncore ( output logic UARTSout ); - logic [`XLEN-1:0] MaskedWriteDataM; - logic [`XLEN-1:0] ReadDataUnmaskedM; - logic [`XLEN-1:0] RdTimM, RdCLINTM, RdGPIOM, RdUARTM; - logic TimEnM, CLINTEnM, GPIOEnM, UARTEnM; - logic [1:0] MemRWdtimM, MemRWclintM, MemRWgpioM, MemRWuartM; + logic [`XLEN-1:0] HWDATA; + logic [`XLEN-1:0] HREADTim, HREADCLINT, HREADGPIO, HREADUART; + logic HSELTim, HSELCLINT, HSELGPIO, PreHSELUART, HSELUART; + logic HRESPTim, HRESPCLINT, HRESPGPIO, HRESPUART; + logic HREADYTim, HREADYCLINT, HREADYGPIO, HREADYUART; + logic MemRW; + logic [1:0] MemRWtim, MemRWclint, MemRWgpio, MemRWuart; logic UARTIntr;// *** will need to tie INTR to an interrupt handler - - // Address decoding - adrdec timdec(AdrM, `TIMBASE, `TIMRANGE, TimEnM); - adrdec clintdec(AdrM, `CLINTBASE, `CLINTRANGE, CLINTEnM); - adrdec gpiodec(AdrM, `GPIOBASE, `GPIORANGE, GPIOEnM); - adrdec uartdec(AdrM, `UARTBASE, `UARTRANGE, UARTEnM); - /*// *** generalize, use configurable - generate - if (`XLEN == 64) - assign TimEnM = ~(|AdrM[`XLEN-1:32]) & AdrM[31] & ~(|AdrM[30:19]); // 0x000...80000000 - 0x000...8007FFFF - else - assign TimEnM = AdrM[31] & ~(|AdrM[30:19]); // 0x80000000 - 0x8007FFFF - endgenerate - assign CLINTEnM = ~(|AdrM[`XLEN-1:26]) & AdrM[25] & ~(|AdrM[24:16]); // 0x02000000-0x0200FFFF - assign GPIOEnM = (AdrM[31:8] == 24'h10012); // 0x10012000-0x100120FF - assign UARTEnM = ~(|AdrM[`XLEN-1:29]) & AdrM[28] & ~(|AdrM[27:3]); // 0x10000000-0x10000007 - */ - // Enable read or write based on decoded address. - assign MemRWdtimM = MemRWM & {2{TimEnM}}; - assign MemRWclintM = MemRWM & {2{CLINTEnM}}; - assign MemRWgpioM = MemRWM & {2{GPIOEnM}}; - assign MemRWuartM = MemRWM & {2{UARTEnM}}; + // AHB Address decoder + adrdec timdec(HADDR, `TIMBASE, `TIMRANGE, HSELTim); + adrdec clintdec(HADDR, `CLINTBASE, `CLINTRANGE, HSELCLINT); + adrdec gpiodec(HADDR, `GPIOBASE, `GPIORANGE, HSELGPIO); + adrdec uartdec(HADDR, `UARTBASE, `UARTRANGE, PreHSELUART); + assign HSELUART = PreHSELUART && (HSIZE == 3'b000); // only byte writes to UART are supported + + // Enable read or write based on decoded address + assign MemRW = {~HWRITE, HWRITE}; + assign MemRWtim = MemRW & {2{HSELTim}}; + assign MemRWclint = MemRW & {2{HSELCLINT}}; + assign MemRWgpio = MemRW & {2{HSELGPIO}}; + assign MemRWuart = MemRW & {2{HSELUART}}; + + // subword accesses: converts HWDATAIN to HWDATA + subwordwrite sww(.*); // tightly integrated memory - dtim dtim(.AdrM(AdrM[18:0]), .*); + dtim dtim(.HADDR(HADDR[18:0]), .*); // memory-mapped I/O peripherals - clint clint(.AdrM(AdrM[15:0]), .*); - gpio gpio(.AdrM(AdrM[7:0]), .*); // *** may want to add GPIO interrupts - uart uart(.TXRDYb(), .RXRDYb(), .INTR(UARTIntr), .SIN(UARTSin), .SOUT(UARTSout), + clint clint(.HADDR(HADDR[15:0]), .*); + gpio gpio(.HADDR(HADDR[7:0]), .*); // *** may want to add GPIO interrupts + uart uart(.HADDR(HADDR[2:0]), .TXRDYb(), .RXRDYb(), .INTR(UARTIntr), .SIN(UARTSin), .SOUT(UARTSout), .DSRb(1'b1), .DCDb(1'b1), .CTSb(1'b0), .RIb(1'b1), .RTSb(), .DTRb(), .OUT1b(), .OUT2b(), .*); - // *** Interface to off-chip memory would appear as another peripheral - - // merge reads - assign ReadDataUnmaskedM = ({`XLEN{TimEnM}} & RdTimM) | ({`XLEN{CLINTEnM}} & RdCLINTM) | - ({`XLEN{GPIOEnM}} & RdGPIOM) | ({`XLEN{UARTEnM}} & RdUARTM); - assign DataAccessFaultM = ~(TimEnM | CLINTEnM | GPIOEnM | UARTEnM); + // mux could also include external memory + // AHB Read Multiplexer + assign HRDATA = ({`XLEN{HSELTim}} & HREADTim) | ({`XLEN{HSELCLINT}} & HREADCLINT) | + ({`XLEN{HSELGPIO}} & HREADGPIO) | ({`XLEN{HSELUART}} & HREADUART); + assign HRESP = HSELTim & HRESPTim | HSELCLINT & HRESPCLINT | HSELGPIO & HRESPGPIO | HSELUART & HRESPUART; + assign HREADY = HSELTim & HREADYTim | HSELCLINT & HREADYCLINT | HSELGPIO & HREADYGPIO | HSELUART & HREADYUART; + + // Faults + assign DataAccessFaultM = ~(HSELTim | HSELCLINT | HSELGPIO | HSELUART); - // subword accesses: converts ReadDataUnmaskedM to ReadDataM and WriteDataM to MaskedWriteDataM - subword subword(.*); endmodule diff --git a/wally-pipelined/src/wallypipelinedhart.sv b/wally-pipelined/src/wallypipelinedhart.sv index 4a9551b24..08998cad4 100644 --- a/wally-pipelined/src/wallypipelinedhart.sv +++ b/wally-pipelined/src/wallypipelinedhart.sv @@ -30,12 +30,9 @@ module wallypipelinedhart ( input logic clk, reset, output logic [`XLEN-1:0] PCF, input logic [31:0] InstrF, - output logic [1:0] MemRWdcuoutM, // *** should be removed when EBU enabled - output logic [2:0] Funct3M, // *** remove when EBU enabled - output logic [`XLEN-1:0] DataAdrM, WriteDataM, // *** - input logic [`XLEN-1:0] ReadDataM, // *** + // Privileged input logic TimerIntM, ExtIntM, SwIntM, - input logic InstrAccessFaultF, + input logic InstrAccessFaultF, input logic DataAccessFaultM, // Bus Interface input logic [`AHBW-1:0] HRDATA, @@ -83,6 +80,12 @@ module wallypipelinedhart ( logic [4:0] SetFflagsM; logic [2:0] FRM_REGW; logic FloatRegWriteW; + + // bus interface to dcu + logic [1:0] MemRWdcuoutM; + logic [2:0] Funct3M; + logic [`XLEN-1:0] DataAdrM, WriteDataM; + logic [`XLEN-1:0] ReadDataM; ifu ifu(.*); // instruction fetch unit: PC, branch prediction, instruction cache @@ -91,8 +94,11 @@ module wallypipelinedhart ( ahblite ebu( .IPAdrD(zero), .IReadD(1'b0), .IRData(), .IReady(), - .DPAdrM(DataAdrM), .DReadM(MemRWM[1]), .DWriteM(MemRWM[0]), .DWDataM(WriteDataM), .DSizeM(2'b11), .DRData(), .DReady(), + .DPAdrM(DataAdrM), .DReadM(MemRWdcuoutM[1]), .DWriteM(MemRWdcuoutM[0]), .DWDataM(WriteDataM), + .DSizeM(Funct3M[1:0]), .DRData(ReadDataM), .DReady(), + .UnsignedLoadM(Funct3M[2]), .*); +// assign UnsignedLoadM = Funct3M[2]; // *** maybe move read extension to dcu /* mdu mdu(.*); // multiply and divide unit diff --git a/wally-pipelined/src/wallypipelinedsoc.sv b/wally-pipelined/src/wallypipelinedsoc.sv index bd1907655..657abb6d1 100644 --- a/wally-pipelined/src/wallypipelinedsoc.sv +++ b/wally-pipelined/src/wallypipelinedsoc.sv @@ -34,8 +34,10 @@ module wallypipelinedsoc ( input logic clk, reset, // AHB Lite Interface - input logic [`AHBW-1:0] HRDATA, - input logic HREADY, HRESP, + // inputs from external memory + input logic [`AHBW-1:0] HRDATAEXT, + input logic HREADYEXT, HRESPEXT, + // outputs to external memory, shared with uncore memory output logic [31:0] HADDR, output logic [`AHBW-1:0] HWDATA, output logic HWRITE, @@ -51,12 +53,14 @@ module wallypipelinedsoc ( output logic UARTSout ); - logic [1:0] MemRWM; - logic [`XLEN-1:0] DataAdrM, WriteDataM; - logic [`XLEN-1:0] PCF, ReadDataM; + // to instruction memory *** remove later + logic [`XLEN-1:0] PCF; logic [31:0] InstrF; - logic [2:0] Funct3M; - logic [1:0] MemRWdcuoutM; + + // Uncore signals + logic [`AHBW-1:0] HRDATA; // from AHB mux in uncore + logic HREADY, HRESP; +// logic UnsignedLoadM; logic InstrAccessFaultF, DataAccessFaultM; logic TimerIntM, SwIntM; // from CLINT logic ExtIntM = 0; // not yet connected @@ -65,5 +69,5 @@ module wallypipelinedsoc ( wallypipelinedhart hart(.*); imem imem(.AdrF(PCF[`XLEN-1:1]), .*); - uncore uncore(.AdrM(DataAdrM), .MemRWM(MemRWdcuoutM), .*); + uncore uncore(.HWDATAIN(HWDATA), .*); endmodule \ No newline at end of file diff --git a/wally-pipelined/testbench/testbench-imperas.sv b/wally-pipelined/testbench/testbench-imperas.sv index 7d73be973..29d5b3415 100644 --- a/wally-pipelined/testbench/testbench-imperas.sv +++ b/wally-pipelined/testbench/testbench-imperas.sv @@ -220,8 +220,8 @@ string tests32i[] = { }; string tests[]; - logic [`AHBW-1:0] HRDATA; - logic HREADY, HRESP; + logic [`AHBW-1:0] HRDATAEXT; + logic HREADYEXT, HRESPEXT; logic [31:0] HADDR; logic [`AHBW-1:0] HWDATA; logic HWRITE; @@ -251,9 +251,9 @@ string tests32i[] = { // instantiate device to be tested assign GPIOPinsIn = 0; assign UARTSin = 1; - assign HREADY = 1; - assign HRESP = 0; - assign HRDATA = 0; + assign HREADYEXT = 1; + assign HRESPEXT = 0; + assign HRDATAEXT = 0; wallypipelinedsoc dut(.*);