Connected AHB bus to Uncore

This commit is contained in:
David Harris 2021-01-29 23:43:48 -05:00
parent 9297376873
commit 9511dcac84
17 changed files with 457 additions and 387 deletions

View File

@ -61,14 +61,14 @@
// Peripheral memory space extends from BASE to BASE+RANGE // 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 // Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits
`define TIMBASE 64'h0000000080000000 `define TIMBASE 32'h80000000
`define TIMRANGE 64'h000000000007FFFF `define TIMRANGE 32'h0007FFFF
`define CLINTBASE 64'h0000000002000000 `define CLINTBASE 32'h02000000
`define CLINTRANGE 64'h000000000000FFFF `define CLINTRANGE 32'h0000FFFF
`define GPIOBASE 64'h0000000010012000 `define GPIOBASE 32'h10012000
`define GPIORANGE 64'h00000000000000FF `define GPIORANGE 32'h000000FF
`define UARTBASE 64'h0000000010000000 `define UARTBASE 32'h10000000
`define UARTRANGE 64'h0000000000000007 `define UARTRANGE 32'h00000007
// Bus Interface width // Bus Interface width
`define AHBW 32 `define AHBW 32

View File

@ -65,14 +65,14 @@
// Peripheral memory space extends from BASE to BASE+RANGE // 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 // Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits
`define TIMBASE 64'h0000000080000000 `define TIMBASE 32'h80000000
`define TIMRANGE 64'h000000000007FFFF `define TIMRANGE 32'h0007FFFF
`define CLINTBASE 64'h0000000002000000 `define CLINTBASE 32'h02000000
`define CLINTRANGE 64'h000000000000FFFF `define CLINTRANGE 32'h0000FFFF
`define GPIOBASE 64'h0000000010012000 `define GPIOBASE 32'h10012000
`define GPIORANGE 64'h00000000000000FF `define GPIORANGE 32'h000000FF
`define UARTBASE 64'h0000000010000000 `define UARTBASE 32'h10000000
`define UARTRANGE 64'h0000000000000007 `define UARTRANGE 32'h00000007
// Test modes // Test modes

View File

@ -64,8 +64,8 @@ add wave -divider
#add wave -hex /testbench/dut/hart/ifu/InstrM #add wave -hex /testbench/dut/hart/ifu/InstrM
add wave /testbench/InstrMName add wave /testbench/InstrMName
add wave /testbench/dut/uncore/dtim/memwrite add wave /testbench/dut/uncore/dtim/memwrite
add wave -hex /testbench/dut/uncore/AdrM add wave -hex /testbench/dut/uncore/HADDR
add wave -hex /testbench/dut/uncore/WriteDataM add wave -hex /testbench/dut/uncore/HWDATA
add wave -divider add wave -divider
add wave -hex /testbench/dut/hart/ifu/PCW add wave -hex /testbench/dut/hart/ifu/PCW
add wave /testbench/InstrWName add wave /testbench/InstrWName

View File

@ -26,19 +26,19 @@
`include "wally-config.vh" `include "wally-config.vh"
module adrdec ( module adrdec (
input logic [`XLEN-1:0] AdrM, input logic [31:0] HADDR,
input logic [`XLEN-1:0] Base, Range, input logic [31:0] Base, Range,
output logic En output logic HSEL
); );
logic [`XLEN-1:0] match; logic [31:0] match;
// determine if an address is in a range starting at the base // determine if an address is in a range starting at the base
// for example, if Base = 0x04002000 and range = 0x00000FFF, // 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 match = (HADDR ~^ Base) | Range;
assign En = &match; assign HSEL = &match;
endmodule endmodule

View File

@ -32,6 +32,8 @@
module ahblite ( module ahblite (
input logic clk, reset, input logic clk, reset,
// Load control
input logic UnsignedLoadM,
// Signals from Instruction Cache // Signals from Instruction Cache
input logic [`XLEN-1:0] IPAdrD, input logic [`XLEN-1:0] IPAdrD,
input logic IReadD, input logic IReadD,
@ -60,6 +62,7 @@ module ahblite (
logic HCLK, HRESETn; logic HCLK, HRESETn;
logic GrantData; logic GrantData;
logic [2:0] ISize; logic [2:0] ISize;
logic [`AHBW-1:0] HRDATAMasked;
assign HCLK = clk; assign HCLK = clk;
assign HRESETn = ~reset; assign HRESETn = ~reset;
@ -77,7 +80,8 @@ module ahblite (
// drive bus outputs // drive bus outputs
assign HADDR = GrantData ? DPAdrM[31:0] : IPAdrD[31:0]; 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 HWRITE = DWriteM; // *** check no level to pulse conversion needed
assign HSIZE = GrantData ? {1'b0, DSizeM} : ISize; assign HSIZE = GrantData ? {1'b0, DSizeM} : ISize;
assign HBURST = 3'b000; // Single burst only supported; consider generalizing for cache fillsfHPROT 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 // Route signals to Instruction and Data Caches
// *** assumes AHBW = XLEN // *** assumes AHBW = XLEN
assign IRData = HRDATA; assign IRData = HRDATAMasked;
assign IReady = HREADY & IReadD & ~GrantData; assign IReady = HREADY & IReadD & ~GrantData;
assign DRData = HRDATA; assign DRData = HRDATAMasked;
assign DReady = HREADY & GrantData; assign DReady = HREADY & GrantData;
// *** consider adding memory access faults based on HRESP being high // *** consider adding memory access faults based on HRESP being high
// InstrAccessFaultF, DataAccessFaultM, // InstrAccessFaultF, DataAccessFaultM,
subwordread swr(.*);
endmodule endmodule

View File

@ -28,10 +28,11 @@
module clint ( module clint (
input logic clk, reset, input logic clk, reset,
input logic [1:0] MemRWclintM, input logic [1:0] MemRWclint,
input logic [15:0] AdrM, input logic [15:0] HADDR,
input logic [`XLEN-1:0] MaskedWriteDataM, input logic [`XLEN-1:0] HWDATA,
output logic [`XLEN-1:0] RdCLINTM, output logic [`XLEN-1:0] HREADCLINT,
output logic HRESPCLINT, HREADYCLINT,
output logic TimerIntM, SwIntM); output logic TimerIntM, SwIntM);
logic [63:0] MTIMECMP, MTIME; logic [63:0] MTIMECMP, MTIME;
@ -40,15 +41,17 @@ module clint (
logic [15:0] entry; logic [15:0] entry;
logic memread, memwrite; logic memread, memwrite;
assign memread = MemRWclintM[1]; assign memread = MemRWclint[1];
assign memwrite = MemRWclintM[0]; assign memwrite = MemRWclint[0];
assign HRESPCLINT = 0; // OK
assign HREADYCLINT = 1; // Respond immediately
// word aligned reads // word aligned reads
generate generate
if (`XLEN==64) if (`XLEN==64)
assign #2 entry = {AdrM[15:3], 3'b000}; assign #2 entry = {HADDR[15:3], 3'b000};
else else
assign #2 entry = {AdrM[15:2], 2'b00}; assign #2 entry = {HADDR[15:2], 2'b00};
endgenerate endgenerate
@ -57,10 +60,10 @@ module clint (
if (`XLEN==64) begin if (`XLEN==64) begin
always_comb begin always_comb begin
case(entry) case(entry)
16'h0000: RdCLINTM = {63'b0, MSIP}; 16'h0000: HREADCLINT = {63'b0, MSIP};
16'h4000: RdCLINTM = MTIMECMP; 16'h4000: HREADCLINT = MTIMECMP;
16'hBFF8: RdCLINTM = MTIME; 16'hBFF8: HREADCLINT = MTIME;
default: RdCLINTM = 0; default: HREADCLINT = 0;
endcase endcase
end end
always_ff @(posedge clk or posedge reset) always_ff @(posedge clk or posedge reset)
@ -70,21 +73,21 @@ module clint (
MTIMECMP <= 0; MTIMECMP <= 0;
// MTIMECMP is not reset // MTIMECMP is not reset
end else if (memwrite) begin end else if (memwrite) begin
if (entry == 16'h0000) MSIP <= MaskedWriteDataM[0]; if (entry == 16'h0000) MSIP <= HWDATA[0];
if (entry == 16'h4000) MTIMECMP <= MaskedWriteDataM; if (entry == 16'h4000) MTIMECMP <= HWDATA;
// MTIME Counter. Eventually change this to run off separate clock. Synchronization then needed // 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; else MTIME <= MTIME + 1;
end end
end else begin // 32-bit end else begin // 32-bit
always_comb begin always_comb begin
case(entry) case(entry)
16'h0000: RdCLINTM = {31'b0, MSIP}; 16'h0000: HREADCLINT = {31'b0, MSIP};
16'h4000: RdCLINTM = MTIMECMP[31:0]; 16'h4000: HREADCLINT = MTIMECMP[31:0];
16'h4004: RdCLINTM = MTIMECMP[63:32]; 16'h4004: HREADCLINT = MTIMECMP[63:32];
16'hBFF8: RdCLINTM = MTIME[31:0]; 16'hBFF8: HREADCLINT = MTIME[31:0];
16'hBFFC: RdCLINTM = MTIME[63:32]; 16'hBFFC: HREADCLINT = MTIME[63:32];
default: RdCLINTM = 0; default: HREADCLINT = 0;
endcase endcase
end end
always_ff @(posedge clk or posedge reset) always_ff @(posedge clk or posedge reset)
@ -94,12 +97,12 @@ module clint (
MTIMECMP <= 0; MTIMECMP <= 0;
// MTIMECMP is not reset // MTIMECMP is not reset
end else if (memwrite) begin end else if (memwrite) begin
if (entry == 16'h0000) MSIP <= MaskedWriteDataM[0]; if (entry == 16'h0000) MSIP <= HWDATA[0];
if (entry == 16'h4000) MTIMECMP[31:0] <= MaskedWriteDataM; if (entry == 16'h4000) MTIMECMP[31:0] <= HWDATA;
if (entry == 16'h4004) MTIMECMP[63:32] <= MaskedWriteDataM; if (entry == 16'h4004) MTIMECMP[63:32] <= HWDATA;
// MTIME Counter. Eventually change this to run off separate clock. Synchronization then needed // MTIME Counter. Eventually change this to run off separate clock. Synchronization then needed
if (entry == 16'hBFF8) MTIME[31:0] <= MaskedWriteDataM; if (entry == 16'hBFF8) MTIME[31:0] <= HWDATA;
else if (entry == 16'hBFFC) MTIME[63:32]<= MaskedWriteDataM; else if (entry == 16'hBFFC) MTIME[63:32]<= HWDATA;
else MTIME <= MTIME + 1; else MTIME <= MTIME + 1;
end end
end end

View File

@ -169,7 +169,7 @@ module csrm #(parameter
PMPCFG0: CSRMReadValM = PMPCFG01_REGW[`XLEN-1:0]; PMPCFG0: CSRMReadValM = PMPCFG01_REGW[`XLEN-1:0];
PMPCFG1: CSRMReadValM = {{(`XLEN-32){1'b0}}, PMPCFG01_REGW[63:31]}; PMPCFG1: CSRMReadValM = {{(`XLEN-32){1'b0}}, PMPCFG01_REGW[63:31]};
PMPCFG2: CSRMReadValM = PMPCFG23_REGW[`XLEN-1:0]; 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; PMPADDR0: CSRMReadValM = PMPADDR0_REGW;
default: begin default: begin
CSRMReadValM = 0; CSRMReadValM = 0;

View File

@ -27,28 +27,32 @@
module dtim ( module dtim (
input logic clk, input logic clk,
input logic [1:0] MemRWdtimM, input logic [1:0] MemRWtim,
// input logic [7:0] ByteMaskM, // input logic [7:0] ByteMaskM,
input logic [18:0] AdrM, input logic [18:0] HADDR,
input logic [`XLEN-1:0] MaskedWriteDataM, input logic [`XLEN-1:0] HWDATA,
output logic [`XLEN-1:0] RdTimM); output logic [`XLEN-1:0] HREADTim,
output logic HRESPTim, HREADYTim
);
logic [`XLEN-1:0] RAM[0:65535]; logic [`XLEN-1:0] RAM[0:65535];
logic [`XLEN-1:0] write; logic [`XLEN-1:0] write;
logic [15:0] entry; logic [15:0] entry;
logic memread, memwrite; logic memread, memwrite;
assign memread = MemRWdtimM[1]; assign memread = MemRWtim[1];
assign memwrite = MemRWdtimM[0]; assign memwrite = MemRWtim[0];
assign HRESPTim = 0; // OK
assign HREADYTim= 1; // Respond immediately; *** extend this
// word aligned reads // word aligned reads
generate generate
if (`XLEN==64) if (`XLEN==64)
assign #2 entry = AdrM[18:3]; assign #2 entry = HADDR[18:3];
else else
assign #2 entry = AdrM[17:2]; assign #2 entry = HADDR[17:2];
endgenerate endgenerate
assign RdTimM = RAM[entry]; assign HREADTim = RAM[entry];
// write each byte based on the byte mask // write each byte based on the byte mask
// UInstantiate a byte-writable memory here if possible // UInstantiate a byte-writable memory here if possible
@ -58,37 +62,37 @@ module dtim (
if (`XLEN==64) begin if (`XLEN==64) begin
always_comb begin always_comb begin
write=RdTimM; write=HREADTim;
if (ByteMaskM[0]) write[7:0] = WriteDataM[7:0]; if (ByteMaskM[0]) write[7:0] = HWDATA[7:0];
if (ByteMaskM[1]) write[15:8] = WriteDataM[15:8]; if (ByteMaskM[1]) write[15:8] = HWDATA[15:8];
if (ByteMaskM[2]) write[23:16] = WriteDataM[23:16]; if (ByteMaskM[2]) write[23:16] = HWDATA[23:16];
if (ByteMaskM[3]) write[31:24] = WriteDataM[31:24]; if (ByteMaskM[3]) write[31:24] = HWDATA[31:24];
if (ByteMaskM[4]) write[39:32] = WriteDataM[39:32]; if (ByteMaskM[4]) write[39:32] = HWDATA[39:32];
if (ByteMaskM[5]) write[47:40] = WriteDataM[47:40]; if (ByteMaskM[5]) write[47:40] = HWDATA[47:40];
if (ByteMaskM[6]) write[55:48] = WriteDataM[55:48]; if (ByteMaskM[6]) write[55:48] = HWDATA[55:48];
if (ByteMaskM[7]) write[63:56] = WriteDataM[63:56]; if (ByteMaskM[7]) write[63:56] = HWDATA[63:56];
end end
always_ff @(posedge clk) always_ff @(posedge clk)
if (memwrite) RAM[AdrM[18:3]] <= write; if (memwrite) RAM[HADDR[18:3]] <= write;
end else begin // 32-bit end else begin // 32-bit
always_comb begin always_comb begin
write=RdTimM; write=HREADTim;
if (ByteMaskM[0]) write[7:0] = WriteDataM[7:0]; if (ByteMaskM[0]) write[7:0] = HWDATA[7:0];
if (ByteMaskM[1]) write[15:8] = WriteDataM[15:8]; if (ByteMaskM[1]) write[15:8] = HWDATA[15:8];
if (ByteMaskM[2]) write[23:16] = WriteDataM[23:16]; if (ByteMaskM[2]) write[23:16] = HWDATA[23:16];
if (ByteMaskM[3]) write[31:24] = WriteDataM[31:24]; if (ByteMaskM[3]) write[31:24] = HWDATA[31:24];
end end
always_ff @(posedge clk) always_ff @(posedge clk)
if (memwrite) RAM[AdrM[17:2]] <= write; if (memwrite) RAM[HADDR[17:2]] <= write;
end end
endgenerate */ endgenerate */
generate generate
if (`XLEN == 64) begin if (`XLEN == 64) begin
always_ff @(posedge clk) always_ff @(posedge clk)
if (memwrite) RAM[AdrM[17:3]] <= MaskedWriteDataM; if (memwrite) RAM[HADDR[17:3]] <= HWDATA;
end else begin end else begin
always_ff @(posedge clk) always_ff @(posedge clk)
if (memwrite) RAM[AdrM[17:2]] <= MaskedWriteDataM; if (memwrite) RAM[HADDR[17:2]] <= HWDATA;
end end
endgenerate endgenerate
endmodule endmodule

View File

@ -29,11 +29,11 @@
module gpio ( module gpio (
input logic clk, reset, input logic clk, reset,
input logic [1:0] MemRWgpioM, input logic [1:0] MemRWgpio,
// input logic [7:0] ByteMaskM, input logic [7:0] HADDR,
input logic [7:0] AdrM, input logic [`XLEN-1:0] HWDATA,
input logic [`XLEN-1:0] MaskedWriteDataM, output logic [`XLEN-1:0] HREADGPIO,
output logic [`XLEN-1:0] RdGPIOM, output logic HRESPGPIO, HREADYGPIO,
input logic [31:0] GPIOPinsIn, input logic [31:0] GPIOPinsIn,
output logic [31:0] GPIOPinsOut, GPIOPinsEn); output logic [31:0] GPIOPinsOut, GPIOPinsEn);
@ -42,15 +42,17 @@ module gpio (
logic [7:0] entry; logic [7:0] entry;
logic memread, memwrite; logic memread, memwrite;
assign memread = MemRWgpioM[1]; assign memread = MemRWgpio[1];
assign memwrite = MemRWgpioM[0]; assign memwrite = MemRWgpio[0];
assign HRESPGPIO = 0; // OK
assign HREADYGPIO = 1; // Respond immediately
// word aligned reads // word aligned reads
generate generate
if (`XLEN==64) if (`XLEN==64)
assign #2 entry = {AdrM[7:3], 3'b000}; assign #2 entry = {HADDR[7:3], 3'b000};
else else
assign #2 entry = {AdrM[7:2], 2'b00}; assign #2 entry = {HADDR[7:2], 2'b00};
endgenerate endgenerate
generate generate
@ -67,10 +69,10 @@ module gpio (
if (`XLEN==64) begin if (`XLEN==64) begin
always_comb begin always_comb begin
case(entry) case(entry)
8'h00: RdGPIOM = {INPUT_EN, INPUT_VAL}; 8'h00: HREADGPIO = {INPUT_EN, INPUT_VAL};
8'h08: RdGPIOM = {OUTPUT_VAL, OUTPUT_EN}; 8'h08: HREADGPIO = {OUTPUT_VAL, OUTPUT_EN};
8'h40: RdGPIOM = 0; // OUT_XOR reads as 0 8'h40: HREADGPIO = 0; // OUT_XOR reads as 0
default: RdGPIOM = 0; default: HREADGPIO = 0;
endcase endcase
end end
always_ff @(posedge clk or posedge reset) always_ff @(posedge clk or posedge reset)
@ -79,19 +81,19 @@ module gpio (
OUTPUT_EN <= 0; OUTPUT_EN <= 0;
OUTPUT_VAL <= 0; // spec indicates synchronous reset (software control) OUTPUT_VAL <= 0; // spec indicates synchronous reset (software control)
end else if (memwrite) begin end else if (memwrite) begin
if (entry == 8'h00) INPUT_EN <= MaskedWriteDataM[63:32]; if (entry == 8'h00) INPUT_EN <= HWDATA[63:32];
if (entry == 8'h08) {OUTPUT_VAL, OUTPUT_EN} <= MaskedWriteDataM; if (entry == 8'h08) {OUTPUT_VAL, OUTPUT_EN} <= HWDATA;
if (entry == 8'h40) OUTPUT_VAL <= OUTPUT_VAL ^ MaskedWriteDataM[31:0]; // OUT_XOR if (entry == 8'h40) OUTPUT_VAL <= OUTPUT_VAL ^ HWDATA[31:0]; // OUT_XOR
end end
end else begin // 32-bit end else begin // 32-bit
always_comb begin always_comb begin
case(entry) case(entry)
8'h00: RdGPIOM = INPUT_VAL; 8'h00: HREADGPIO = INPUT_VAL;
8'h04: RdGPIOM = INPUT_EN; 8'h04: HREADGPIO = INPUT_EN;
8'h08: RdGPIOM = OUTPUT_EN; 8'h08: HREADGPIO = OUTPUT_EN;
8'h0C: RdGPIOM = OUTPUT_VAL; 8'h0C: HREADGPIO = OUTPUT_VAL;
8'h40: RdGPIOM = 0; // OUT_XOR reads as 0 8'h40: HREADGPIO = 0; // OUT_XOR reads as 0
default: RdGPIOM = 0; default: HREADGPIO = 0;
endcase endcase
end end
always_ff @(posedge clk or posedge reset) always_ff @(posedge clk or posedge reset)
@ -100,10 +102,10 @@ module gpio (
OUTPUT_EN <= 0; OUTPUT_EN <= 0;
//OUTPUT_VAL <= 0;// spec indicates synchronous rset (software control) //OUTPUT_VAL <= 0;// spec indicates synchronous rset (software control)
end else if (memwrite) begin end else if (memwrite) begin
if (entry == 8'h04) INPUT_EN <= MaskedWriteDataM; if (entry == 8'h04) INPUT_EN <= HWDATA;
if (entry == 8'h08) OUTPUT_EN <= MaskedWriteDataM; if (entry == 8'h08) OUTPUT_EN <= HWDATA;
if (entry == 8'h0C) OUTPUT_VAL <= MaskedWriteDataM; if (entry == 8'h0C) OUTPUT_VAL <= HWDATA;
if (entry == 8'h40) OUTPUT_VAL <= OUTPUT_VAL ^ MaskedWriteDataM; // OUT_XOR if (entry == 8'h40) OUTPUT_VAL <= OUTPUT_VAL ^ HWDATA; // OUT_XOR
end end
end end
endgenerate endgenerate

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -29,11 +29,11 @@
module uart ( module uart (
input logic clk, reset, input logic clk, reset,
input logic [1:0] MemRWuartM, input logic [1:0] MemRWuart,
// input logic [7:0] ByteMaskM, input logic [2:0] HADDR,
input logic [`XLEN-1:0] AdrM, input logic [`XLEN-1:0] HWDATA,
input logic [`XLEN-1:0] MaskedWriteDataM, output logic [`XLEN-1:0] HREADUART,
output logic [`XLEN-1:0] RdUARTM, output logic HRESPUART, HREADYUART,
input logic SIN, DSRb, DCDb, CTSb, RIb, // from E1A driver from RS232 interface 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 SOUT, RTSb, DTRb, // to E1A driver to RS232 interface
output logic OUT1b, OUT2b, INTR, TXRDYb, RXRDYb); // to CPU output logic OUT1b, OUT2b, INTR, TXRDYb, RXRDYb); // to CPU
@ -44,33 +44,35 @@ module uart (
logic [7:0] Din, Dout; logic [7:0] Din, Dout;
// rename processor interface signals to match PC16550D and provide one-byte interface // rename processor interface signals to match PC16550D and provide one-byte interface
assign MEMRb = ~MemRWuartM[1]; assign MEMRb = ~MemRWuart[1];
assign MEMWb = ~MemRWuartM[0]; assign MEMWb = ~MemRWuart[0];
assign A = AdrM[2:0]; assign A = HADDR[2:0];
assign HRESPUART = 0; // OK
assign HREADYUART = 1; // Respond immediately
generate generate
if (`XLEN == 64) begin if (`XLEN == 64) begin
always_comb begin always_comb begin
RdUARTM = {Dout, Dout, Dout, Dout, Dout, Dout, Dout, Dout}; HREADUART = {Dout, Dout, Dout, Dout, Dout, Dout, Dout, Dout};
case (AdrM[2:0]) case (HADDR)
3'b000: Din = MaskedWriteDataM[7:0]; 3'b000: Din = HWDATA[7:0];
3'b001: Din = MaskedWriteDataM[15:8]; 3'b001: Din = HWDATA[15:8];
3'b010: Din = MaskedWriteDataM[23:16]; 3'b010: Din = HWDATA[23:16];
3'b011: Din = MaskedWriteDataM[31:24]; 3'b011: Din = HWDATA[31:24];
3'b100: Din = MaskedWriteDataM[39:32]; 3'b100: Din = HWDATA[39:32];
3'b101: Din = MaskedWriteDataM[47:40]; 3'b101: Din = HWDATA[47:40];
3'b110: Din = MaskedWriteDataM[55:48]; 3'b110: Din = HWDATA[55:48];
3'b111: Din = MaskedWriteDataM[63:56]; 3'b111: Din = HWDATA[63:56];
endcase endcase
end end
end else begin // 32-bit end else begin // 32-bit
always_comb begin always_comb begin
RdUARTM = {Dout, Dout, Dout, Dout}; HREADUART = {Dout, Dout, Dout, Dout};
case (AdrM[1:0]) case (HADDR[1:0])
2'b00: Din = MaskedWriteDataM[7:0]; 2'b00: Din = HWDATA[7:0];
2'b01: Din = MaskedWriteDataM[15:8]; 2'b01: Din = HWDATA[15:8];
2'b10: Din = MaskedWriteDataM[23:16]; 2'b10: Din = HWDATA[23:16];
2'b11: Din = MaskedWriteDataM[31:24]; 2'b11: Din = HWDATA[31:24];
endcase endcase
end end
end end

View File

@ -30,11 +30,20 @@
// *** and use memread signal to reduce power when reads aren't needed // *** and use memread signal to reduce power when reads aren't needed
module uncore ( module uncore (
input logic clk, reset, 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 // 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, output logic DataAccessFaultM,
// peripheral pins // peripheral pins
output logic TimerIntM, SwIntM, output logic TimerIntM, SwIntM,
@ -44,56 +53,53 @@ module uncore (
output logic UARTSout output logic UARTSout
); );
logic [`XLEN-1:0] MaskedWriteDataM; logic [`XLEN-1:0] HWDATA;
logic [`XLEN-1:0] ReadDataUnmaskedM; logic [`XLEN-1:0] HREADTim, HREADCLINT, HREADGPIO, HREADUART;
logic [`XLEN-1:0] RdTimM, RdCLINTM, RdGPIOM, RdUARTM; logic HSELTim, HSELCLINT, HSELGPIO, PreHSELUART, HSELUART;
logic TimEnM, CLINTEnM, GPIOEnM, UARTEnM; logic HRESPTim, HRESPCLINT, HRESPGPIO, HRESPUART;
logic [1:0] MemRWdtimM, MemRWclintM, MemRWgpioM, MemRWuartM; 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 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 // AHB Address decoder
generate adrdec timdec(HADDR, `TIMBASE, `TIMRANGE, HSELTim);
if (`XLEN == 64) adrdec clintdec(HADDR, `CLINTBASE, `CLINTRANGE, HSELCLINT);
assign TimEnM = ~(|AdrM[`XLEN-1:32]) & AdrM[31] & ~(|AdrM[30:19]); // 0x000...80000000 - 0x000...8007FFFF adrdec gpiodec(HADDR, `GPIOBASE, `GPIORANGE, HSELGPIO);
else adrdec uartdec(HADDR, `UARTBASE, `UARTRANGE, PreHSELUART);
assign TimEnM = AdrM[31] & ~(|AdrM[30:19]); // 0x80000000 - 0x8007FFFF assign HSELUART = PreHSELUART && (HSIZE == 3'b000); // only byte writes to UART are supported
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. // Enable read or write based on decoded address
assign MemRWdtimM = MemRWM & {2{TimEnM}}; assign MemRW = {~HWRITE, HWRITE};
assign MemRWclintM = MemRWM & {2{CLINTEnM}}; assign MemRWtim = MemRW & {2{HSELTim}};
assign MemRWgpioM = MemRWM & {2{GPIOEnM}}; assign MemRWclint = MemRW & {2{HSELCLINT}};
assign MemRWuartM = MemRWM & {2{UARTEnM}}; assign MemRWgpio = MemRW & {2{HSELGPIO}};
assign MemRWuart = MemRW & {2{HSELUART}};
// subword accesses: converts HWDATAIN to HWDATA
subwordwrite sww(.*);
// tightly integrated memory // tightly integrated memory
dtim dtim(.AdrM(AdrM[18:0]), .*); dtim dtim(.HADDR(HADDR[18:0]), .*);
// memory-mapped I/O peripherals // memory-mapped I/O peripherals
clint clint(.AdrM(AdrM[15:0]), .*); clint clint(.HADDR(HADDR[15:0]), .*);
gpio gpio(.AdrM(AdrM[7:0]), .*); // *** may want to add GPIO interrupts gpio gpio(.HADDR(HADDR[7:0]), .*); // *** may want to add GPIO interrupts
uart uart(.TXRDYb(), .RXRDYb(), .INTR(UARTIntr), .SIN(UARTSin), .SOUT(UARTSout), 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), .DSRb(1'b1), .DCDb(1'b1), .CTSb(1'b0), .RIb(1'b1),
.RTSb(), .DTRb(), .OUT1b(), .OUT2b(), .*); .RTSb(), .DTRb(), .OUT1b(), .OUT2b(), .*);
// *** Interface to off-chip memory would appear as another peripheral // 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;
// merge reads // Faults
assign ReadDataUnmaskedM = ({`XLEN{TimEnM}} & RdTimM) | ({`XLEN{CLINTEnM}} & RdCLINTM) | assign DataAccessFaultM = ~(HSELTim | HSELCLINT | HSELGPIO | HSELUART);
({`XLEN{GPIOEnM}} & RdGPIOM) | ({`XLEN{UARTEnM}} & RdUARTM);
assign DataAccessFaultM = ~(TimEnM | CLINTEnM | GPIOEnM | UARTEnM);
// subword accesses: converts ReadDataUnmaskedM to ReadDataM and WriteDataM to MaskedWriteDataM
subword subword(.*);
endmodule endmodule

View File

@ -30,10 +30,7 @@ module wallypipelinedhart (
input logic clk, reset, input logic clk, reset,
output logic [`XLEN-1:0] PCF, output logic [`XLEN-1:0] PCF,
input logic [31:0] InstrF, input logic [31:0] InstrF,
output logic [1:0] MemRWdcuoutM, // *** should be removed when EBU enabled // Privileged
output logic [2:0] Funct3M, // *** remove when EBU enabled
output logic [`XLEN-1:0] DataAdrM, WriteDataM, // ***
input logic [`XLEN-1:0] ReadDataM, // ***
input logic TimerIntM, ExtIntM, SwIntM, input logic TimerIntM, ExtIntM, SwIntM,
input logic InstrAccessFaultF, input logic InstrAccessFaultF,
input logic DataAccessFaultM, input logic DataAccessFaultM,
@ -84,6 +81,12 @@ module wallypipelinedhart (
logic [2:0] FRM_REGW; logic [2:0] FRM_REGW;
logic FloatRegWriteW; 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 ifu ifu(.*); // instruction fetch unit: PC, branch prediction, instruction cache
ieu ieu(.*); // inteber execution unit: integer register file, datapath and controller ieu ieu(.*); // inteber execution unit: integer register file, datapath and controller
@ -91,8 +94,11 @@ module wallypipelinedhart (
ahblite ebu( ahblite ebu(
.IPAdrD(zero), .IReadD(1'b0), .IRData(), .IReady(), .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 mdu mdu(.*); // multiply and divide unit

View File

@ -34,8 +34,10 @@
module wallypipelinedsoc ( module wallypipelinedsoc (
input logic clk, reset, input logic clk, reset,
// AHB Lite Interface // AHB Lite Interface
input logic [`AHBW-1:0] HRDATA, // inputs from external memory
input logic HREADY, HRESP, 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 [31:0] HADDR,
output logic [`AHBW-1:0] HWDATA, output logic [`AHBW-1:0] HWDATA,
output logic HWRITE, output logic HWRITE,
@ -51,12 +53,14 @@ module wallypipelinedsoc (
output logic UARTSout output logic UARTSout
); );
logic [1:0] MemRWM; // to instruction memory *** remove later
logic [`XLEN-1:0] DataAdrM, WriteDataM; logic [`XLEN-1:0] PCF;
logic [`XLEN-1:0] PCF, ReadDataM;
logic [31:0] InstrF; 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 InstrAccessFaultF, DataAccessFaultM;
logic TimerIntM, SwIntM; // from CLINT logic TimerIntM, SwIntM; // from CLINT
logic ExtIntM = 0; // not yet connected logic ExtIntM = 0; // not yet connected
@ -65,5 +69,5 @@ module wallypipelinedsoc (
wallypipelinedhart hart(.*); wallypipelinedhart hart(.*);
imem imem(.AdrF(PCF[`XLEN-1:1]), .*); imem imem(.AdrF(PCF[`XLEN-1:1]), .*);
uncore uncore(.AdrM(DataAdrM), .MemRWM(MemRWdcuoutM), .*); uncore uncore(.HWDATAIN(HWDATA), .*);
endmodule endmodule

View File

@ -220,8 +220,8 @@ string tests32i[] = {
}; };
string tests[]; string tests[];
logic [`AHBW-1:0] HRDATA; logic [`AHBW-1:0] HRDATAEXT;
logic HREADY, HRESP; logic HREADYEXT, HRESPEXT;
logic [31:0] HADDR; logic [31:0] HADDR;
logic [`AHBW-1:0] HWDATA; logic [`AHBW-1:0] HWDATA;
logic HWRITE; logic HWRITE;
@ -251,9 +251,9 @@ string tests32i[] = {
// instantiate device to be tested // instantiate device to be tested
assign GPIOPinsIn = 0; assign GPIOPinsIn = 0;
assign UARTSin = 1; assign UARTSin = 1;
assign HREADY = 1; assign HREADYEXT = 1;
assign HRESP = 0; assign HRESPEXT = 0;
assign HRDATA = 0; assign HRDATAEXT = 0;
wallypipelinedsoc dut(.*); wallypipelinedsoc dut(.*);