Uncore is now parameterized.

This commit is contained in:
Ross Thompson 2023-05-26 16:24:12 -05:00
parent 340aac0934
commit b8474b208e
9 changed files with 114 additions and 132 deletions

View File

@ -25,31 +25,29 @@
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh"
module ahbapbbridge #(PERIPHS = 2) (
module ahbapbbridge import cvw::*; #(parameter cvw_t P, PERIPHS = 2) (
input logic HCLK, HRESETn,
input logic [PERIPHS-1:0] HSEL,
input logic [`PA_BITS-1:0] HADDR,
input logic [`XLEN-1:0] HWDATA,
input logic [`XLEN/8-1:0] HWSTRB,
input logic [P.PA_BITS-1:0] HADDR,
input logic [P.XLEN-1:0] HWDATA,
input logic [P.XLEN/8-1:0] HWSTRB,
input logic HWRITE,
input logic [1:0] HTRANS,
input logic HREADY,
// input logic [3:0] HPROT, // not used
output logic [`XLEN-1:0] HRDATA,
output logic [P.XLEN-1:0] HRDATA,
output logic HRESP, HREADYOUT,
output logic PCLK, PRESETn,
output logic [PERIPHS-1:0] PSEL,
output logic PWRITE,
output logic PENABLE,
output logic [31:0] PADDR,
output logic [`XLEN-1:0] PWDATA,
output logic [P.XLEN-1:0] PWDATA,
// output logic [2:0] PPROT, // not used
output logic [`XLEN/8-1:0] PSTRB,
output logic [P.XLEN/8-1:0] PSTRB,
// output logic PWAKEUP // not used
input logic [PERIPHS-1:0] PREADY,
input var [PERIPHS-1:0][`XLEN-1:0] PRDATA
input var [PERIPHS-1:0][P.XLEN-1:0] PRDATA
);
logic initTrans, initTransSel, initTransSelD;

View File

@ -27,17 +27,15 @@
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh"
module clint_apb (
module clint_apb import cvw::*; #(parameter cvw_t P) (
input logic PCLK, PRESETn,
input logic PSEL,
input logic [15:0] PADDR,
input logic [`XLEN-1:0] PWDATA,
input logic [`XLEN/8-1:0] PSTRB,
input logic [P.XLEN-1:0] PWDATA,
input logic [P.XLEN/8-1:0] PSTRB,
input logic PWRITE,
input logic PENABLE,
output logic [`XLEN-1:0] PRDATA,
output logic [P.XLEN-1:0] PRDATA,
output logic PREADY,
output logic [63:0] MTIME,
output logic MTimerInt, MSwInt
@ -53,7 +51,7 @@ module clint_apb (
assign PREADY = 1'b1; // CLINT never takes >1 cycle to respond
// word aligned reads
if (`XLEN==64) assign #2 entry = {PADDR[15:3], 3'b000};
if (P.XLEN==64) assign #2 entry = {PADDR[15:3], 3'b000};
else assign #2 entry = {PADDR[15:2], 2'b00};
// DH 2/20/21: Eventually allow MTIME to run off a separate clock
@ -63,7 +61,7 @@ module clint_apb (
// Use req and ack signals synchronized across the clock domains.
// register access
if (`XLEN==64) begin:clint // 64-bit
if (P.XLEN==64) begin:clint // 64-bit
always @(posedge PCLK) begin
case(entry)
16'h0000: PRDATA <= {63'b0, MSIP};
@ -79,7 +77,7 @@ module clint_apb (
end else if (memwrite) begin
if (entry == 16'h0000) MSIP <= PWDATA[0];
if (entry == 16'h4000) begin
for(i=0;i<`XLEN/8;i++)
for(i=0;i<P.XLEN/8;i++)
if(PSTRB[i])
MTIMECMP[i*8 +: 8] <= PWDATA[i*8 +: 8]; // ***dh: this notation isn't in book yet - maybe from Ross
end
@ -93,7 +91,7 @@ module clint_apb (
MTIME <= 0;
end else if (memwrite & entry == 16'hBFF8) begin
// MTIME Counter. Eventually change this to run off separate clock. Synchronization then needed
for(j=0;j<`XLEN/8;j++)
for(j=0;j<P.XLEN/8;j++)
if(PSTRB[j])
MTIME[j*8 +: 8] <= PWDATA[j*8 +: 8];
end else MTIME <= MTIME + 1;
@ -116,11 +114,11 @@ module clint_apb (
end else if (memwrite) begin
if (entry == 16'h0000) MSIP <= PWDATA[0];
if (entry == 16'h4000)
for(j=0;j<`XLEN/8;j++)
for(j=0;j<P.XLEN/8;j++)
if(PSTRB[j])
MTIMECMP[j*8 +: 8] <= PWDATA[j*8 +: 8];
if (entry == 16'h4004)
for(j=0;j<`XLEN/8;j++)
for(j=0;j<P.XLEN/8;j++)
if(PSTRB[j])
MTIMECMP[32 + j*8 +: 8] <= PWDATA[j*8 +: 8];
// MTIME Counter. Eventually change this to run off separate clock. Synchronization then needed
@ -133,12 +131,12 @@ module clint_apb (
MTIME <= 0;
// MTIMECMP is not reset
end else if (memwrite & (entry == 16'hBFF8)) begin
for(i=0;i<`XLEN/8;i++)
for(i=0;i<P.XLEN/8;i++)
if(PSTRB[i])
MTIME[i*8 +: 8] <= PWDATA[i*8 +: 8];
end else if (memwrite & (entry == 16'hBFFC)) begin
// MTIME Counter. Eventually change this to run off separate clock. Synchronization then needed
for(i=0;i<`XLEN/8;i++)
for(i=0;i<P.XLEN/8;i++)
if(PSTRB[i])
MTIME[32 + i*8 +: 8]<= PWDATA[i*8 +: 8];
end else MTIME <= MTIME + 1;
@ -151,13 +149,13 @@ module clint_apb (
endmodule
module timeregsync(
module timeregsync import cvw::*; #(parameter cvw_t P) (
input logic clk, resetn,
input logic we0, we1,
input logic [`XLEN-1:0] wd,
input logic [P.XLEN-1:0] wd,
output logic [63:0] q);
if (`XLEN==64)
if (P.XLEN==64)
always_ff @(posedge clk or negedge resetn)
if (~resetn) q <= 0;
else if (we0) q <= wd;
@ -170,14 +168,14 @@ module timeregsync(
else q <= q + 1;
endmodule
module timereg(
module timereg import cvw::*; #(parameter cvw_t P) (
input logic PCLK, PRESETn, TIMECLK,
input logic we0, we1,
input logic [`XLEN-1:0] PWDATA,
input logic [P.XLEN-1:0] PWDATA,
output logic [63:0] MTIME,
output logic done);
// if (`TIMEBASE_SYNC) begin:timereg // use PCLK for MTIME
// if (P.TIMEBASE_SYNC) begin:timereg // use PCLK for MTIME
if (1) begin:timereg // use PCLK for MTIME
timregsync timeregsync(.clk(PCLK), .resetn(PRESETn), .we0, .we1, .wd(PWDATA), .q(MTIME));
assign done = 1; // immediately completes
@ -192,7 +190,7 @@ module timereg(
// There is no back pressure on instructions, so if multiple counter writes occur ***
logic req, req_sync, ack, we0_stored, we1_stored, ack_stored, resetn_sync;
logic [`XLEN-1:0] wd_stored;
logic [P.XLEN-1:0] wd_stored;
logic [63:0] time_int, time_int_gc, time_gc, MTIME_GC;
// When a write enable is asserted for a cycle, sample the enables and data and raise a request until it is acknowledged
@ -216,7 +214,7 @@ module timereg(
// synchronize the acknowledge back to the PCLK domain to indicate the request was handled and can be lowered
sync async(PCLK, req_sync, ack);
timeregsync timeregsync(.clk(TIMECLK), .resetn(resetn_sync), .we0(we0_stored), .we1(we1_stored), .wd(wd_stored), .q(time_int));
timeregsync #(P) timeregsync(.clk(TIMECLK), .resetn(resetn_sync), .we0(we0_stored), .we1(we1_stored), .wd(wd_stored), .q(time_int));
binarytogray b2g(time_int, time_int_gc);
flop gcreg(TIMECLK, time_int_gc, time_gc);
@ -225,7 +223,7 @@ module timereg(
end
endmodule
module binarytogray #(parameter N = `XLEN) (
module binarytogray #(parameter N) (
input logic [N-1:0] b,
output logic [N-1:0] g);
@ -234,7 +232,7 @@ module binarytogray #(parameter N = `XLEN) (
assign g = b ^ {1'b0, b[N-1:1]};
endmodule
module graytobinary #(parameter N = `XLEN) (
module graytobinary #(parameter N) (
input logic [N-1:0] g,
output logic [N-1:0] b);

View File

@ -28,17 +28,15 @@
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh"
module gpio_apb (
module gpio_apb import cvw::*; #(parameter cvw_t P) (
input logic PCLK, PRESETn,
input logic PSEL,
input logic [7:0] PADDR,
input logic [`XLEN-1:0] PWDATA,
input logic [`XLEN/8-1:0] PSTRB,
input logic [P.XLEN-1:0] PWDATA,
input logic [P.XLEN/8-1:0] PSTRB,
input logic PWRITE,
input logic PENABLE,
output logic [`XLEN-1:0] PRDATA,
output logic [P.XLEN-1:0] PRDATA,
output logic PREADY,
input logic [31:0] iof0, iof1,
input logic [31:0] GPIOIN,
@ -62,7 +60,7 @@ module gpio_apb (
// account for subword read/write circuitry
// -- Note GPIO registers are 32 bits no matter what; access them with LW SW.
// (At least that's what I think when FE310 spec says "only naturally aligned 32-bit accesses are supported")
if (`XLEN == 64) begin
if (P.XLEN == 64) begin
assign Din = entry[2] ? PWDATA[63:32] : PWDATA[31:0];
assign PRDATA = entry[2] ? {Dout,32'b0} : {32'b0,Dout};
end else begin // 32-bit
@ -138,7 +136,7 @@ module gpio_apb (
// chip i/o
// connect OUT to IN for loopback testing
if (`GPIO_LOOPBACK_TEST) assign input0d = ((output_en & GPIOOUT) | (~output_en & GPIOIN)) & input_en;
if (P.GPIO_LOOPBACK_TEST) assign input0d = ((output_en & GPIOOUT) | (~output_en & GPIOIN)) & input_en;
else assign input0d = GPIOIN & input_en;
// synchroninzer for inputs

View File

@ -31,9 +31,7 @@
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh"
`define N `PLIC_NUM_SRC
`define N P.PLIC_NUM_SRC
// number of interrupt sources
// does not include source 0, which does not connect to anything according to spec
// up to 63 sources supported; in the future, allow up to 1023 sources
@ -42,15 +40,15 @@
// number of conexts
// hardcoded to 2 contexts for now; later upgrade to arbitrary (up to 15872) contexts
module plic_apb (
module plic_apb import cvw::*; #(parameter cvw_t P) (
input logic PCLK, PRESETn,
input logic PSEL,
input logic [27:0] PADDR,
input logic [`XLEN-1:0] PWDATA,
input logic [`XLEN/8-1:0] PSTRB,
input logic [P.XLEN-1:0] PWDATA,
input logic [P.XLEN/8-1:0] PSTRB,
input logic PWRITE,
input logic PENABLE,
output logic [`XLEN-1:0] PRDATA,
output logic [P.XLEN-1:0] PRDATA,
output logic PREADY,
input logic UARTIntr,GPIOIntr,
output logic MExtInt, SExtInt
@ -86,7 +84,7 @@ module plic_apb (
// account for subword read/write circuitry
// -- Note PLIC registers are 32 bits no matter what; access them with LW SW.
if (`XLEN == 64) begin
if (P.XLEN == 64) begin
assign Din = entry[2] ? PWDATA[63:32] : PWDATA[31:0];
assign PRDATA = entry[2] ? {Dout,32'b0} : {32'b0,Dout};
end else begin // 32-bit
@ -94,6 +92,8 @@ module plic_apb (
assign Din = PWDATA[31:0];
end
if (P.PLIC_NUM_SRC_LT_32) `define PLIC_NUM_SRC_LT_32
// ==================
// Register Interface
// ==================
@ -101,9 +101,9 @@ module plic_apb (
// resetting
if (~PRESETn) begin
intPriority <= #1 {`N{3'b0}};
intEn <= #1 {2{`N'b0}};
intEn <= #1 {2*`N{1'b0}};
intThreshold <= #1 {2{3'b0}};
intInProgress <= #1 `N'b0;
intInProgress <= #1 {`N{1'b0}};
// writing
end else begin
if (memwrite)
@ -120,12 +120,12 @@ module plic_apb (
24'h002084: intEn[1][`N:32] <= #1 Din[31:0];
`endif
24'h200000: intThreshold[0] <= #1 Din[2:0];
24'h200004: intInProgress <= #1 intInProgress & ~(`N'b1 << (Din[5:0]-1)); // lower "InProgress" to signify completion
24'h200004: intInProgress <= #1 intInProgress & ~({{`N-1{1'b0}}, 1'b1} << (Din[5:0]-1)); // lower "InProgress" to signify completion
24'h201000: intThreshold[1] <= #1 Din[2:0];
24'h201004: intInProgress <= #1 intInProgress & ~(`N'b1 << (Din[5:0]-1)); // lower "InProgress" to signify completion
24'h201004: intInProgress <= #1 intInProgress & ~({{`N-1{1'b0}}, 1'b1} << (Din[5:0]-1)); // lower "InProgress" to signify completion
endcase
// Read synchronously because a read can have side effect of changing intInProgress
if (memread)
if (memread) begin
casez(entry)
24'h000000: Dout <= #1 32'b0; // there is no intPriority[0]
24'h0000??: Dout <= #1 {29'b0,intPriority[entry[7:2]]};
@ -145,31 +145,27 @@ module plic_apb (
24'h200000: Dout <= #1 {29'b0,intThreshold[0]};
24'h200004: begin
Dout <= #1 {26'b0,intClaim[0]};
intInProgress <= #1 intInProgress | (`N'b1 << (intClaim[0]-1)); // claimed requests are currently in progress of being serviced until they are completed
intInProgress <= #1 intInProgress | ({{`N-1{1'b0}}, 1'b1} << (intClaim[0]-1)); // claimed requests are currently in progress of being serviced until they are completed
end
24'h201000: Dout <= #1 {29'b0,intThreshold[1]};
24'h201004: begin
Dout <= #1 {26'b0,intClaim[1]};
intInProgress <= #1 intInProgress | (`N'b1 << (intClaim[1]-1)); // claimed requests are currently in progress of being serviced until they are completed
intInProgress <= #1 intInProgress | ({{`N-1{1'b0}}, 1'b1} << (intClaim[1]-1)); // claimed requests are currently in progress of being serviced until they are completed
end
default: Dout <= #1 32'h0; // invalid access
endcase
else Dout <= #1 32'h0;
end else Dout <= #1 32'h0;
end
end
// connect sources to requests
always_comb begin
requests = `N'b0;
`ifdef PLIC_GPIO_ID
requests[`PLIC_GPIO_ID] = GPIOIntr;
`endif
`ifdef PLIC_UART_ID
requests[`PLIC_UART_ID] = UARTIntr;
`endif
requests = {`N{1'b0}};
if(P.PLIC_GPIO_ID != 0) requests[P.PLIC_GPIO_ID] = GPIOIntr;
if(P.PLIC_UART_ID != 0) requests[P.PLIC_UART_ID] = UARTIntr;
end
// pending interrupt requests
// pending interrupt request
assign nextIntPending = (intPending | requests) & ~intInProgress;
flopr #(`N) intPendingFlop(PCLK,~PRESETn,nextIntPending,intPending);

View File

@ -26,27 +26,26 @@
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh"
`define RAM_LATENCY 0
module ram_ahb #(parameter BASE=0, RANGE = 65535) (
module ram_ahb import cvw::*; #(parameter cvw_t P, BASE=0, RANGE = 65535) (
input logic HCLK, HRESETn,
input logic HSELRam,
input logic [`PA_BITS-1:0] HADDR,
input logic [P.PA_BITS-1:0] HADDR,
input logic HWRITE,
input logic HREADY,
input logic [1:0] HTRANS,
input logic [`XLEN-1:0] HWDATA,
input logic [`XLEN/8-1:0] HWSTRB,
output logic [`XLEN-1:0] HREADRam,
input logic [P.XLEN-1:0] HWDATA,
input logic [P.XLEN/8-1:0] HWSTRB,
output logic [P.XLEN-1:0] HREADRam,
output logic HRESPRam, HREADYRam
);
localparam ADDR_WIDTH = $clog2(RANGE/8);
localparam OFFSET = $clog2(`XLEN/8);
localparam OFFSET = $clog2(P.XLEN/8);
logic [`XLEN/8-1:0] ByteMask;
logic [`PA_BITS-1:0] HADDRD, RamAddr;
logic [P.XLEN/8-1:0] ByteMask;
logic [P.PA_BITS-1:0] HADDRD, RamAddr;
logic initTrans;
logic memwrite, memwriteD, memread;
logic nextHREADYRam;
@ -59,7 +58,7 @@ module ram_ahb #(parameter BASE=0, RANGE = 65535) (
assign memread = initTrans & ~HWRITE;
flopenr #(1) memwritereg(HCLK, ~HRESETn, HREADY, memwrite, memwriteD);
flopenr #(`PA_BITS) haddrreg(HCLK, ~HRESETn, HREADY, HADDR, HADDRD);
flopenr #(P.PA_BITS) haddrreg(HCLK, ~HRESETn, HREADY, HADDR, HADDRD);
// Stall on a read after a write because the RAM can't take both adddresses on the same cycle
assign nextHREADYRam = (~(memwriteD & memread)) & ~DelayReady;
@ -68,10 +67,10 @@ module ram_ahb #(parameter BASE=0, RANGE = 65535) (
assign HRESPRam = 0; // OK
// On writes or during a wait state, use address delayed by one cycle to sync RamAddr with HWDATA or hold stalled address
mux2 #(`PA_BITS) adrmux(HADDR, HADDRD, memwriteD | ~HREADY, RamAddr);
mux2 #(P.PA_BITS) adrmux(HADDR, HADDRD, memwriteD | ~HREADY, RamAddr);
// single-ported RAM
ram1p1rwbe #(.DEPTH(RANGE/8), .WIDTH(`XLEN)) memory(.clk(HCLK), .ce(1'b1),
ram1p1rwbe #(.DEPTH(RANGE/8), .WIDTH(P.XLEN)) memory(.clk(HCLK), .ce(1'b1),
.addr(RamAddr[ADDR_WIDTH+OFFSET-1:OFFSET]), .we(memwriteD), .din(HWDATA), .bwe(HWSTRB), .dout(HREADRam));

View File

@ -26,27 +26,25 @@
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh"
module rom_ahb #(parameter BASE=0, RANGE = 65535) (
module rom_ahb import cvw::*; #(parameter cvw_t P, BASE=0, RANGE = 65535) (
input logic HCLK, HRESETn,
input logic HSELRom,
input logic [`PA_BITS-1:0] HADDR,
input logic [P.PA_BITS-1:0] HADDR,
input logic HREADY,
input logic [1:0] HTRANS,
output logic [`XLEN-1:0] HREADRom,
output logic [P.XLEN-1:0] HREADRom,
output logic HRESPRom, HREADYRom
);
localparam ADDR_WIDTH = $clog2(RANGE/8);
localparam OFFSET = $clog2(`XLEN/8);
localparam OFFSET = $clog2(P.XLEN/8);
// Never stalls
assign HREADYRom = 1'b1;
assign HRESPRom = 0; // OK
// single-ported ROM
rom1p1r #(ADDR_WIDTH, `XLEN, `FPGA)
rom1p1r #(ADDR_WIDTH, P.XLEN, P.FPGA)
memory(.clk(HCLK), .ce(1'b1), .addr(HADDR[ADDR_WIDTH+OFFSET-1:OFFSET]), .dout(HREADRom));
endmodule

View File

@ -33,10 +33,9 @@
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh"
/* verilator lint_off UNOPTFLAT */
module uartPC16550D(
module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
// Processor Interface
input logic PCLK, PRESETn, // UART clock and active low reset
input logic [2:0] A, // address input (8 registers)
@ -73,7 +72,7 @@ module uartPC16550D(
// Baud and rx/tx timing
logic baudpulse, txbaudpulse, rxbaudpulse; // high one system clk cycle each baud/16 period
logic [16+`UART_PRESCALE-1:0] baudcount;
logic [16+UART_PRESCALE-1:0] baudcount;
logic [3:0] rxoversampledcnt, txoversampledcnt; // count oversampled-by-16
logic [3:0] rxbitsreceived, txbitssent;
statetype rxstate, txstate;
@ -137,7 +136,7 @@ module uartPC16550D(
if (~PRESETn) begin // Table 3 Reset Configuration
IER <= #1 4'b0;
FCR <= #1 8'b0;
if (`QEMU) LCR <= #1 8'b0; else LCR <= #1 8'b11; // fpga only **** BUG
if (QEMU) LCR <= #1 8'b0; else LCR <= #1 8'b11; // fpga only **** BUG
MCR <= #1 5'b0;
LSR <= #1 8'b01100000;
MSR <= #1 4'b0;
@ -225,7 +224,7 @@ module uartPC16550D(
baudcount <= #1 baudpulseComb ? 1 : baudcount +1;
end
assign baudpulseComb = (baudcount == {DLM, DLL, {(`UART_PRESCALE){1'b0}}});
assign baudpulseComb = (baudcount == {DLM, DLL, {(UART_PRESCALE){1'b0}}});
assign txbaudpulse = baudpulse;
assign BAUDOUTb = ~baudpulse;
@ -260,7 +259,7 @@ module uartPC16550D(
end
// ***explain why
if(`QEMU) assign rxcentered = rxbaudpulse & (rxoversampledcnt[1:0] == 2'b10); // implies rxstate = UART_ACTIVE
if(QEMU) assign rxcentered = rxbaudpulse & (rxoversampledcnt[1:0] == 2'b10); // implies rxstate = UART_ACTIVE
else assign rxcentered = rxbaudpulse & (rxoversampledcnt == 4'b1000); // implies rxstate = UART_ACTIVE
assign rxbitsexpected = 4'd1 + (4'd5 + {2'b00, LCR[1:0]}) + {3'b000, LCR[3]} + 4'd1; // start bit + data bits + (parity bit) + stop bit
@ -390,7 +389,7 @@ module uartPC16550D(
assign txbitsexpected = 4'd1 + (4'd5 + {2'b00, LCR[1:0]}) + {3'b000, LCR[3]} + 4'd1 + {3'b000, LCR[2]} - 4'd1; // start bit + data bits + (parity bit) + stop bit(s) - 1
// *** explain; is this necessary?
if (`QEMU) assign txnextbit = txbaudpulse & (txoversampledcnt[1:0] == 2'b00); // implies txstate = UART_ACTIVE
if (QEMU) assign txnextbit = txbaudpulse & (txoversampledcnt[1:0] == 2'b00); // implies txstate = UART_ACTIVE
else assign txnextbit = txbaudpulse & (txoversampledcnt == 4'b0000); // implies txstate = UART_ACTIVE
///////////////////////////////////////////

View File

@ -28,17 +28,15 @@
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh"
module uart_apb (
module uart_apb import cvw::*; #(parameter cvw_t P) (
input logic PCLK, PRESETn,
input logic PSEL,
input logic [2:0] PADDR,
input logic [`XLEN-1:0] PWDATA,
input logic [`XLEN/8-1:0] PSTRB,
input logic [P.XLEN-1:0] PWDATA,
input logic [P.XLEN/8-1:0] PSTRB,
input logic PWRITE,
input logic PENABLE,
output logic [`XLEN-1:0] PRDATA,
output logic [P.XLEN-1:0] PRDATA,
output logic PREADY,
input logic SIN, DSRb, DCDb, CTSb, RIb, // from E1A driver from RS232 interface
output logic SOUT, RTSb, DTRb, // to E1A driver to RS232 interface
@ -56,7 +54,7 @@ module uart_apb (
assign MEMRb = ~memread;
assign MEMWb = ~memwrite;
if (`XLEN == 64) begin:uart
if (P.XLEN == 64) begin:uart
always_comb begin
PRDATA = {Dout, Dout, Dout, Dout, Dout, Dout, Dout, Dout};
case (entry)
@ -84,7 +82,7 @@ module uart_apb (
logic BAUDOUTb; // loop tx clock BAUDOUTb back to rx clock RCLK
// *** make sure reads don't occur on UART unless fully selected because they could change state. This applies to all peripherals
uartPC16550D u(
uartPC16550D #(P.UART_PRESCALE, P.QEMU) u(
// Processor Interface
.PCLK, .PRESETn,
.A(entry), .Din,

View File

@ -27,24 +27,22 @@
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh"
module uncore import cvw::*; #(parameter cvw_t P)(
// AHB Bus Interface
input logic HCLK, HRESETn,
input logic TIMECLK,
input logic [`PA_BITS-1:0] HADDR,
input logic [`AHBW-1:0] HWDATA,
input logic [`XLEN/8-1:0] HWSTRB,
input logic [P.PA_BITS-1:0] HADDR,
input logic [P.AHBW-1:0] HWDATA,
input logic [P.XLEN/8-1:0] HWSTRB,
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 [P.AHBW-1:0] HRDATAEXT,
input logic HREADYEXT, HRESPEXT,
output logic [`AHBW-1:0] HRDATA,
output logic [P.AHBW-1:0] HRDATA,
output logic HREADY, HRESP,
output logic HSELEXT,
// peripheral pins
@ -62,14 +60,14 @@ module uncore import cvw::*; #(parameter cvw_t P)(
output logic SDCCLK // SD Card clock
);
logic [`XLEN-1:0] HREADRam, HREADSDC;
logic [P.XLEN-1:0] HREADRam, HREADSDC;
logic [10:0] HSELRegions;
logic HSELDTIM, HSELIROM, HSELRam, HSELCLINT, HSELPLIC, HSELGPIO, HSELUART, HSELSDC;
logic HSELDTIMD, HSELIROMD, HSELEXTD, HSELRamD, HSELCLINTD, HSELPLICD, HSELGPIOD, HSELUARTD, HSELSDCD;
logic HRESPRam, HRESPSDC;
logic HREADYRam, HRESPSDCD;
logic [`XLEN-1:0] HREADBootRom;
logic [P.XLEN-1:0] HREADBootRom;
logic HSELBootRom, HSELBootRomD, HRESPBootRom, HREADYBootRom, HREADYSDC;
logic HSELNoneD;
logic UARTIntr,GPIOIntr;
@ -78,10 +76,10 @@ module uncore import cvw::*; #(parameter cvw_t P)(
logic PCLK, PRESETn, PWRITE, PENABLE;
logic [3:0] PSEL, PREADY;
logic [31:0] PADDR;
logic [`XLEN-1:0] PWDATA;
logic [`XLEN/8-1:0] PSTRB;
logic [3:0][`XLEN-1:0] PRDATA;
logic [`XLEN-1:0] HREADBRIDGE;
logic [P.XLEN-1:0] PWDATA;
logic [P.XLEN/8-1:0] PSTRB;
logic [3:0][P.XLEN-1:0] PRDATA;
logic [P.XLEN-1:0] HREADBRIDGE;
logic HRESPBRIDGE, HREADYBRIDGE, HSELBRIDGE, HSELBRIDGED;
// Determine which region of physical memory (if any) is being accessed
@ -93,52 +91,52 @@ module uncore import cvw::*; #(parameter cvw_t P)(
assign {HSELDTIM, HSELIROM, HSELEXT, HSELBootRom, HSELRam, HSELCLINT, HSELGPIO, HSELUART, HSELPLIC, HSELSDC} = HSELRegions[10:1];
// AHB -> APB bridge
ahbapbbridge #(4) ahbapbbridge (
ahbapbbridge #(P, 4) ahbapbbridge (
.HCLK, .HRESETn, .HSEL({HSELUART, HSELPLIC, HSELCLINT, HSELGPIO}), .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HTRANS, .HREADY,
.HRDATA(HREADBRIDGE), .HRESP(HRESPBRIDGE), .HREADYOUT(HREADYBRIDGE),
.PCLK, .PRESETn, .PSEL, .PWRITE, .PENABLE, .PADDR, .PWDATA, .PSTRB, .PREADY, .PRDATA);
assign HSELBRIDGE = HSELGPIO | HSELCLINT | HSELPLIC | HSELUART; // if any of the bridge signals are selected
// on-chip RAM
if (`UNCORE_RAM_SUPPORTED) begin : ram
ram_ahb #(.BASE(`UNCORE_RAM_BASE), .RANGE(`UNCORE_RAM_RANGE)) ram (
if (P.UNCORE_RAM_SUPPORTED) begin : ram
ram_ahb #(.P(P), .BASE(P.UNCORE_RAM_BASE), .RANGE(P.UNCORE_RAM_RANGE)) ram (
.HCLK, .HRESETn, .HSELRam, .HADDR, .HWRITE, .HREADY,
.HTRANS, .HWDATA, .HWSTRB, .HREADRam, .HRESPRam, .HREADYRam);
end
if (`BOOTROM_SUPPORTED) begin : bootrom
rom_ahb #(.BASE(`BOOTROM_BASE), .RANGE(`BOOTROM_RANGE))
if (P.BOOTROM_SUPPORTED) begin : bootrom
rom_ahb #(.P(P), .BASE(P.BOOTROM_BASE), .RANGE(P.BOOTROM_RANGE))
bootrom(.HCLK, .HRESETn, .HSELRom(HSELBootRom), .HADDR, .HREADY, .HTRANS,
.HREADRom(HREADBootRom), .HRESPRom(HRESPBootRom), .HREADYRom(HREADYBootRom));
end
// memory-mapped I/O peripherals
if (`CLINT_SUPPORTED == 1) begin : clint
clint_apb clint(.PCLK, .PRESETn, .PSEL(PSEL[1]), .PADDR(PADDR[15:0]), .PWDATA, .PSTRB, .PWRITE, .PENABLE,
if (P.CLINT_SUPPORTED == 1) begin : clint
clint_apb #(P) clint(.PCLK, .PRESETn, .PSEL(PSEL[1]), .PADDR(PADDR[15:0]), .PWDATA, .PSTRB, .PWRITE, .PENABLE,
.PRDATA(PRDATA[1]), .PREADY(PREADY[1]), .MTIME(MTIME_CLINT), .MTimerInt, .MSwInt);
end else begin : clint
assign MTIME_CLINT = 0;
assign MTimerInt = 0; assign MSwInt = 0;
end
if (`PLIC_SUPPORTED == 1) begin : plic
plic_apb plic(.PCLK, .PRESETn, .PSEL(PSEL[2]), .PADDR(PADDR[27:0]), .PWDATA, .PSTRB, .PWRITE, .PENABLE,
if (P.PLIC_SUPPORTED == 1) begin : plic
plic_apb #(P) plic(.PCLK, .PRESETn, .PSEL(PSEL[2]), .PADDR(PADDR[27:0]), .PWDATA, .PSTRB, .PWRITE, .PENABLE,
.PRDATA(PRDATA[2]), .PREADY(PREADY[2]), .UARTIntr, .GPIOIntr, .MExtInt, .SExtInt);
end else begin : plic
assign MExtInt = 0;
assign SExtInt = 0;
end
if (`GPIO_SUPPORTED == 1) begin : gpio
gpio_apb gpio(
if (P.GPIO_SUPPORTED == 1) begin : gpio
gpio_apb #(P) gpio(
.PCLK, .PRESETn, .PSEL(PSEL[0]), .PADDR(PADDR[7:0]), .PWDATA, .PSTRB, .PWRITE, .PENABLE,
.PRDATA(PRDATA[0]), .PREADY(PREADY[0]),
.iof0(), .iof1(), .GPIOIN, .GPIOOUT, .GPIOEN, .GPIOIntr);
end else begin : gpio
assign GPIOOUT = 0; assign GPIOEN = 0; assign GPIOIntr = 0;
end
if (`UART_SUPPORTED == 1) begin : uart
uart_apb uart(
if (P.UART_SUPPORTED == 1) begin : uart
uart_apb #(P) uart(
.PCLK, .PRESETn, .PSEL(PSEL[3]), .PADDR(PADDR[2:0]), .PWDATA, .PSTRB, .PWRITE, .PENABLE,
.PRDATA(PRDATA[3]), .PREADY(PREADY[3]),
.SIN(UARTSin), .DSRb(1'b1), .DCDb(1'b1), .CTSb(1'b0), .RIb(1'b1), // from E1A driver from RS232 interface
@ -147,7 +145,7 @@ module uncore import cvw::*; #(parameter cvw_t P)(
end else begin : uart
assign UARTSout = 0; assign UARTIntr = 0;
end
if (`SDC_SUPPORTED == 1) begin : sdc
if (P.SDC_SUPPORTED == 1) begin : sdc
SDC SDC(.HCLK, .HRESETn, .HSELSDC, .HADDR(HADDR[4:0]), .HWRITE, .HREADY, .HTRANS,
.HWDATA, .HREADSDC, .HRESPSDC, .HREADYSDC,
// sdc interface
@ -162,11 +160,11 @@ module uncore import cvw::*; #(parameter cvw_t P)(
end
// AHB Read Multiplexer
assign HRDATA = ({`XLEN{HSELRamD}} & HREADRam) |
({`XLEN{HSELEXTD}} & HRDATAEXT) |
({`XLEN{HSELBRIDGED}} & HREADBRIDGE) |
({`XLEN{HSELBootRomD}} & HREADBootRom) |
({`XLEN{HSELSDCD}} & HREADSDC);
assign HRDATA = ({P.XLEN{HSELRamD}} & HREADRam) |
({P.XLEN{HSELEXTD}} & HRDATAEXT) |
({P.XLEN{HSELBRIDGED}} & HREADBRIDGE) |
({P.XLEN{HSELBootRomD}} & HREADBootRom) |
({P.XLEN{HSELSDCD}} & HREADSDC);
assign HRESP = HSELRamD & HRESPRam |
HSELEXTD & HRESPEXT |