Connected AHB bus to Uncore

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

@ -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(.*);