mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Uncore is now parameterized.
This commit is contained in:
parent
340aac0934
commit
b8474b208e
@ -25,31 +25,29 @@
|
|||||||
// and limitations under the License.
|
// and limitations under the License.
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
`include "wally-config.vh"
|
module ahbapbbridge import cvw::*; #(parameter cvw_t P, PERIPHS = 2) (
|
||||||
|
|
||||||
module ahbapbbridge #(PERIPHS = 2) (
|
|
||||||
input logic HCLK, HRESETn,
|
input logic HCLK, HRESETn,
|
||||||
input logic [PERIPHS-1:0] HSEL,
|
input logic [PERIPHS-1:0] HSEL,
|
||||||
input logic [`PA_BITS-1:0] HADDR,
|
input logic [P.PA_BITS-1:0] HADDR,
|
||||||
input logic [`XLEN-1:0] HWDATA,
|
input logic [P.XLEN-1:0] HWDATA,
|
||||||
input logic [`XLEN/8-1:0] HWSTRB,
|
input logic [P.XLEN/8-1:0] HWSTRB,
|
||||||
input logic HWRITE,
|
input logic HWRITE,
|
||||||
input logic [1:0] HTRANS,
|
input logic [1:0] HTRANS,
|
||||||
input logic HREADY,
|
input logic HREADY,
|
||||||
// input logic [3:0] HPROT, // not used
|
// 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 HRESP, HREADYOUT,
|
||||||
output logic PCLK, PRESETn,
|
output logic PCLK, PRESETn,
|
||||||
output logic [PERIPHS-1:0] PSEL,
|
output logic [PERIPHS-1:0] PSEL,
|
||||||
output logic PWRITE,
|
output logic PWRITE,
|
||||||
output logic PENABLE,
|
output logic PENABLE,
|
||||||
output logic [31:0] PADDR,
|
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 [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
|
// output logic PWAKEUP // not used
|
||||||
input logic [PERIPHS-1:0] PREADY,
|
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;
|
logic initTrans, initTransSel, initTransSelD;
|
||||||
|
@ -27,17 +27,15 @@
|
|||||||
// and limitations under the License.
|
// and limitations under the License.
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
`include "wally-config.vh"
|
module clint_apb import cvw::*; #(parameter cvw_t P) (
|
||||||
|
|
||||||
module clint_apb (
|
|
||||||
input logic PCLK, PRESETn,
|
input logic PCLK, PRESETn,
|
||||||
input logic PSEL,
|
input logic PSEL,
|
||||||
input logic [15:0] PADDR,
|
input logic [15:0] PADDR,
|
||||||
input logic [`XLEN-1:0] PWDATA,
|
input logic [P.XLEN-1:0] PWDATA,
|
||||||
input logic [`XLEN/8-1:0] PSTRB,
|
input logic [P.XLEN/8-1:0] PSTRB,
|
||||||
input logic PWRITE,
|
input logic PWRITE,
|
||||||
input logic PENABLE,
|
input logic PENABLE,
|
||||||
output logic [`XLEN-1:0] PRDATA,
|
output logic [P.XLEN-1:0] PRDATA,
|
||||||
output logic PREADY,
|
output logic PREADY,
|
||||||
output logic [63:0] MTIME,
|
output logic [63:0] MTIME,
|
||||||
output logic MTimerInt, MSwInt
|
output logic MTimerInt, MSwInt
|
||||||
@ -53,7 +51,7 @@ module clint_apb (
|
|||||||
assign PREADY = 1'b1; // CLINT never takes >1 cycle to respond
|
assign PREADY = 1'b1; // CLINT never takes >1 cycle to respond
|
||||||
|
|
||||||
// word aligned reads
|
// 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};
|
else assign #2 entry = {PADDR[15:2], 2'b00};
|
||||||
|
|
||||||
// DH 2/20/21: Eventually allow MTIME to run off a separate clock
|
// 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.
|
// Use req and ack signals synchronized across the clock domains.
|
||||||
|
|
||||||
// register access
|
// register access
|
||||||
if (`XLEN==64) begin:clint // 64-bit
|
if (P.XLEN==64) begin:clint // 64-bit
|
||||||
always @(posedge PCLK) begin
|
always @(posedge PCLK) begin
|
||||||
case(entry)
|
case(entry)
|
||||||
16'h0000: PRDATA <= {63'b0, MSIP};
|
16'h0000: PRDATA <= {63'b0, MSIP};
|
||||||
@ -79,7 +77,7 @@ module clint_apb (
|
|||||||
end else if (memwrite) begin
|
end else if (memwrite) begin
|
||||||
if (entry == 16'h0000) MSIP <= PWDATA[0];
|
if (entry == 16'h0000) MSIP <= PWDATA[0];
|
||||||
if (entry == 16'h4000) begin
|
if (entry == 16'h4000) begin
|
||||||
for(i=0;i<`XLEN/8;i++)
|
for(i=0;i<P.XLEN/8;i++)
|
||||||
if(PSTRB[i])
|
if(PSTRB[i])
|
||||||
MTIMECMP[i*8 +: 8] <= PWDATA[i*8 +: 8]; // ***dh: this notation isn't in book yet - maybe from Ross
|
MTIMECMP[i*8 +: 8] <= PWDATA[i*8 +: 8]; // ***dh: this notation isn't in book yet - maybe from Ross
|
||||||
end
|
end
|
||||||
@ -93,7 +91,7 @@ module clint_apb (
|
|||||||
MTIME <= 0;
|
MTIME <= 0;
|
||||||
end else if (memwrite & entry == 16'hBFF8) begin
|
end else if (memwrite & entry == 16'hBFF8) begin
|
||||||
// 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
|
||||||
for(j=0;j<`XLEN/8;j++)
|
for(j=0;j<P.XLEN/8;j++)
|
||||||
if(PSTRB[j])
|
if(PSTRB[j])
|
||||||
MTIME[j*8 +: 8] <= PWDATA[j*8 +: 8];
|
MTIME[j*8 +: 8] <= PWDATA[j*8 +: 8];
|
||||||
end else MTIME <= MTIME + 1;
|
end else MTIME <= MTIME + 1;
|
||||||
@ -116,11 +114,11 @@ module clint_apb (
|
|||||||
end else if (memwrite) begin
|
end else if (memwrite) begin
|
||||||
if (entry == 16'h0000) MSIP <= PWDATA[0];
|
if (entry == 16'h0000) MSIP <= PWDATA[0];
|
||||||
if (entry == 16'h4000)
|
if (entry == 16'h4000)
|
||||||
for(j=0;j<`XLEN/8;j++)
|
for(j=0;j<P.XLEN/8;j++)
|
||||||
if(PSTRB[j])
|
if(PSTRB[j])
|
||||||
MTIMECMP[j*8 +: 8] <= PWDATA[j*8 +: 8];
|
MTIMECMP[j*8 +: 8] <= PWDATA[j*8 +: 8];
|
||||||
if (entry == 16'h4004)
|
if (entry == 16'h4004)
|
||||||
for(j=0;j<`XLEN/8;j++)
|
for(j=0;j<P.XLEN/8;j++)
|
||||||
if(PSTRB[j])
|
if(PSTRB[j])
|
||||||
MTIMECMP[32 + j*8 +: 8] <= PWDATA[j*8 +: 8];
|
MTIMECMP[32 + j*8 +: 8] <= PWDATA[j*8 +: 8];
|
||||||
// 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
|
||||||
@ -133,12 +131,12 @@ module clint_apb (
|
|||||||
MTIME <= 0;
|
MTIME <= 0;
|
||||||
// MTIMECMP is not reset
|
// MTIMECMP is not reset
|
||||||
end else if (memwrite & (entry == 16'hBFF8)) begin
|
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])
|
if(PSTRB[i])
|
||||||
MTIME[i*8 +: 8] <= PWDATA[i*8 +: 8];
|
MTIME[i*8 +: 8] <= PWDATA[i*8 +: 8];
|
||||||
end else if (memwrite & (entry == 16'hBFFC)) begin
|
end else if (memwrite & (entry == 16'hBFFC)) begin
|
||||||
// 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
|
||||||
for(i=0;i<`XLEN/8;i++)
|
for(i=0;i<P.XLEN/8;i++)
|
||||||
if(PSTRB[i])
|
if(PSTRB[i])
|
||||||
MTIME[32 + i*8 +: 8]<= PWDATA[i*8 +: 8];
|
MTIME[32 + i*8 +: 8]<= PWDATA[i*8 +: 8];
|
||||||
end else MTIME <= MTIME + 1;
|
end else MTIME <= MTIME + 1;
|
||||||
@ -151,13 +149,13 @@ module clint_apb (
|
|||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
module timeregsync(
|
module timeregsync import cvw::*; #(parameter cvw_t P) (
|
||||||
input logic clk, resetn,
|
input logic clk, resetn,
|
||||||
input logic we0, we1,
|
input logic we0, we1,
|
||||||
input logic [`XLEN-1:0] wd,
|
input logic [P.XLEN-1:0] wd,
|
||||||
output logic [63:0] q);
|
output logic [63:0] q);
|
||||||
|
|
||||||
if (`XLEN==64)
|
if (P.XLEN==64)
|
||||||
always_ff @(posedge clk or negedge resetn)
|
always_ff @(posedge clk or negedge resetn)
|
||||||
if (~resetn) q <= 0;
|
if (~resetn) q <= 0;
|
||||||
else if (we0) q <= wd;
|
else if (we0) q <= wd;
|
||||||
@ -170,14 +168,14 @@ module timeregsync(
|
|||||||
else q <= q + 1;
|
else q <= q + 1;
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
module timereg(
|
module timereg import cvw::*; #(parameter cvw_t P) (
|
||||||
input logic PCLK, PRESETn, TIMECLK,
|
input logic PCLK, PRESETn, TIMECLK,
|
||||||
input logic we0, we1,
|
input logic we0, we1,
|
||||||
input logic [`XLEN-1:0] PWDATA,
|
input logic [P.XLEN-1:0] PWDATA,
|
||||||
output logic [63:0] MTIME,
|
output logic [63:0] MTIME,
|
||||||
output logic done);
|
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
|
if (1) begin:timereg // use PCLK for MTIME
|
||||||
timregsync timeregsync(.clk(PCLK), .resetn(PRESETn), .we0, .we1, .wd(PWDATA), .q(MTIME));
|
timregsync timeregsync(.clk(PCLK), .resetn(PRESETn), .we0, .we1, .wd(PWDATA), .q(MTIME));
|
||||||
assign done = 1; // immediately completes
|
assign done = 1; // immediately completes
|
||||||
@ -192,7 +190,7 @@ module timereg(
|
|||||||
// There is no back pressure on instructions, so if multiple counter writes occur ***
|
// 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 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;
|
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
|
// 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
|
// synchronize the acknowledge back to the PCLK domain to indicate the request was handled and can be lowered
|
||||||
sync async(PCLK, req_sync, ack);
|
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);
|
binarytogray b2g(time_int, time_int_gc);
|
||||||
flop gcreg(TIMECLK, time_int_gc, time_gc);
|
flop gcreg(TIMECLK, time_int_gc, time_gc);
|
||||||
|
|
||||||
@ -225,7 +223,7 @@ module timereg(
|
|||||||
end
|
end
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
module binarytogray #(parameter N = `XLEN) (
|
module binarytogray #(parameter N) (
|
||||||
input logic [N-1:0] b,
|
input logic [N-1:0] b,
|
||||||
output logic [N-1:0] g);
|
output logic [N-1:0] g);
|
||||||
|
|
||||||
@ -234,7 +232,7 @@ module binarytogray #(parameter N = `XLEN) (
|
|||||||
assign g = b ^ {1'b0, b[N-1:1]};
|
assign g = b ^ {1'b0, b[N-1:1]};
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
module graytobinary #(parameter N = `XLEN) (
|
module graytobinary #(parameter N) (
|
||||||
input logic [N-1:0] g,
|
input logic [N-1:0] g,
|
||||||
output logic [N-1:0] b);
|
output logic [N-1:0] b);
|
||||||
|
|
||||||
|
@ -28,17 +28,15 @@
|
|||||||
// and limitations under the License.
|
// and limitations under the License.
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
`include "wally-config.vh"
|
module gpio_apb import cvw::*; #(parameter cvw_t P) (
|
||||||
|
|
||||||
module gpio_apb (
|
|
||||||
input logic PCLK, PRESETn,
|
input logic PCLK, PRESETn,
|
||||||
input logic PSEL,
|
input logic PSEL,
|
||||||
input logic [7:0] PADDR,
|
input logic [7:0] PADDR,
|
||||||
input logic [`XLEN-1:0] PWDATA,
|
input logic [P.XLEN-1:0] PWDATA,
|
||||||
input logic [`XLEN/8-1:0] PSTRB,
|
input logic [P.XLEN/8-1:0] PSTRB,
|
||||||
input logic PWRITE,
|
input logic PWRITE,
|
||||||
input logic PENABLE,
|
input logic PENABLE,
|
||||||
output logic [`XLEN-1:0] PRDATA,
|
output logic [P.XLEN-1:0] PRDATA,
|
||||||
output logic PREADY,
|
output logic PREADY,
|
||||||
input logic [31:0] iof0, iof1,
|
input logic [31:0] iof0, iof1,
|
||||||
input logic [31:0] GPIOIN,
|
input logic [31:0] GPIOIN,
|
||||||
@ -62,7 +60,7 @@ module gpio_apb (
|
|||||||
// account for subword read/write circuitry
|
// account for subword read/write circuitry
|
||||||
// -- Note GPIO registers are 32 bits no matter what; access them with LW SW.
|
// -- 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")
|
// (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 Din = entry[2] ? PWDATA[63:32] : PWDATA[31:0];
|
||||||
assign PRDATA = entry[2] ? {Dout,32'b0} : {32'b0,Dout};
|
assign PRDATA = entry[2] ? {Dout,32'b0} : {32'b0,Dout};
|
||||||
end else begin // 32-bit
|
end else begin // 32-bit
|
||||||
@ -138,7 +136,7 @@ module gpio_apb (
|
|||||||
|
|
||||||
// chip i/o
|
// chip i/o
|
||||||
// connect OUT to IN for loopback testing
|
// 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;
|
else assign input0d = GPIOIN & input_en;
|
||||||
|
|
||||||
// synchroninzer for inputs
|
// synchroninzer for inputs
|
||||||
|
@ -31,9 +31,7 @@
|
|||||||
// and limitations under the License.
|
// and limitations under the License.
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
`include "wally-config.vh"
|
`define N P.PLIC_NUM_SRC
|
||||||
|
|
||||||
`define N `PLIC_NUM_SRC
|
|
||||||
// number of interrupt sources
|
// number of interrupt sources
|
||||||
// does not include source 0, which does not connect to anything according to spec
|
// 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
|
// up to 63 sources supported; in the future, allow up to 1023 sources
|
||||||
@ -42,15 +40,15 @@
|
|||||||
// number of conexts
|
// number of conexts
|
||||||
// hardcoded to 2 contexts for now; later upgrade to arbitrary (up to 15872) contexts
|
// 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 PCLK, PRESETn,
|
||||||
input logic PSEL,
|
input logic PSEL,
|
||||||
input logic [27:0] PADDR,
|
input logic [27:0] PADDR,
|
||||||
input logic [`XLEN-1:0] PWDATA,
|
input logic [P.XLEN-1:0] PWDATA,
|
||||||
input logic [`XLEN/8-1:0] PSTRB,
|
input logic [P.XLEN/8-1:0] PSTRB,
|
||||||
input logic PWRITE,
|
input logic PWRITE,
|
||||||
input logic PENABLE,
|
input logic PENABLE,
|
||||||
output logic [`XLEN-1:0] PRDATA,
|
output logic [P.XLEN-1:0] PRDATA,
|
||||||
output logic PREADY,
|
output logic PREADY,
|
||||||
input logic UARTIntr,GPIOIntr,
|
input logic UARTIntr,GPIOIntr,
|
||||||
output logic MExtInt, SExtInt
|
output logic MExtInt, SExtInt
|
||||||
@ -86,7 +84,7 @@ module plic_apb (
|
|||||||
|
|
||||||
// account for subword read/write circuitry
|
// account for subword read/write circuitry
|
||||||
// -- Note PLIC registers are 32 bits no matter what; access them with LW SW.
|
// -- 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 Din = entry[2] ? PWDATA[63:32] : PWDATA[31:0];
|
||||||
assign PRDATA = entry[2] ? {Dout,32'b0} : {32'b0,Dout};
|
assign PRDATA = entry[2] ? {Dout,32'b0} : {32'b0,Dout};
|
||||||
end else begin // 32-bit
|
end else begin // 32-bit
|
||||||
@ -94,6 +92,8 @@ module plic_apb (
|
|||||||
assign Din = PWDATA[31:0];
|
assign Din = PWDATA[31:0];
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if (P.PLIC_NUM_SRC_LT_32) `define PLIC_NUM_SRC_LT_32
|
||||||
|
|
||||||
// ==================
|
// ==================
|
||||||
// Register Interface
|
// Register Interface
|
||||||
// ==================
|
// ==================
|
||||||
@ -101,9 +101,9 @@ module plic_apb (
|
|||||||
// resetting
|
// resetting
|
||||||
if (~PRESETn) begin
|
if (~PRESETn) begin
|
||||||
intPriority <= #1 {`N{3'b0}};
|
intPriority <= #1 {`N{3'b0}};
|
||||||
intEn <= #1 {2{`N'b0}};
|
intEn <= #1 {2*`N{1'b0}};
|
||||||
intThreshold <= #1 {2{3'b0}};
|
intThreshold <= #1 {2{3'b0}};
|
||||||
intInProgress <= #1 `N'b0;
|
intInProgress <= #1 {`N{1'b0}};
|
||||||
// writing
|
// writing
|
||||||
end else begin
|
end else begin
|
||||||
if (memwrite)
|
if (memwrite)
|
||||||
@ -120,12 +120,12 @@ module plic_apb (
|
|||||||
24'h002084: intEn[1][`N:32] <= #1 Din[31:0];
|
24'h002084: intEn[1][`N:32] <= #1 Din[31:0];
|
||||||
`endif
|
`endif
|
||||||
24'h200000: intThreshold[0] <= #1 Din[2:0];
|
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'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
|
endcase
|
||||||
// Read synchronously because a read can have side effect of changing intInProgress
|
// Read synchronously because a read can have side effect of changing intInProgress
|
||||||
if (memread)
|
if (memread) begin
|
||||||
casez(entry)
|
casez(entry)
|
||||||
24'h000000: Dout <= #1 32'b0; // there is no intPriority[0]
|
24'h000000: Dout <= #1 32'b0; // there is no intPriority[0]
|
||||||
24'h0000??: Dout <= #1 {29'b0,intPriority[entry[7:2]]};
|
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'h200000: Dout <= #1 {29'b0,intThreshold[0]};
|
||||||
24'h200004: begin
|
24'h200004: begin
|
||||||
Dout <= #1 {26'b0,intClaim[0]};
|
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
|
end
|
||||||
24'h201000: Dout <= #1 {29'b0,intThreshold[1]};
|
24'h201000: Dout <= #1 {29'b0,intThreshold[1]};
|
||||||
24'h201004: begin
|
24'h201004: begin
|
||||||
Dout <= #1 {26'b0,intClaim[1]};
|
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
|
end
|
||||||
default: Dout <= #1 32'h0; // invalid access
|
default: Dout <= #1 32'h0; // invalid access
|
||||||
endcase
|
endcase
|
||||||
else Dout <= #1 32'h0;
|
end else Dout <= #1 32'h0;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
// connect sources to requests
|
// connect sources to requests
|
||||||
always_comb begin
|
always_comb begin
|
||||||
requests = `N'b0;
|
requests = {`N{1'b0}};
|
||||||
`ifdef PLIC_GPIO_ID
|
if(P.PLIC_GPIO_ID != 0) requests[P.PLIC_GPIO_ID] = GPIOIntr;
|
||||||
requests[`PLIC_GPIO_ID] = GPIOIntr;
|
if(P.PLIC_UART_ID != 0) requests[P.PLIC_UART_ID] = UARTIntr;
|
||||||
`endif
|
|
||||||
`ifdef PLIC_UART_ID
|
|
||||||
requests[`PLIC_UART_ID] = UARTIntr;
|
|
||||||
`endif
|
|
||||||
end
|
end
|
||||||
|
|
||||||
// pending interrupt requests
|
// pending interrupt request
|
||||||
assign nextIntPending = (intPending | requests) & ~intInProgress;
|
assign nextIntPending = (intPending | requests) & ~intInProgress;
|
||||||
flopr #(`N) intPendingFlop(PCLK,~PRESETn,nextIntPending,intPending);
|
flopr #(`N) intPendingFlop(PCLK,~PRESETn,nextIntPending,intPending);
|
||||||
|
|
||||||
|
@ -26,27 +26,26 @@
|
|||||||
// and limitations under the License.
|
// and limitations under the License.
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
`include "wally-config.vh"
|
|
||||||
`define RAM_LATENCY 0
|
`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 HCLK, HRESETn,
|
||||||
input logic HSELRam,
|
input logic HSELRam,
|
||||||
input logic [`PA_BITS-1:0] HADDR,
|
input logic [P.PA_BITS-1:0] HADDR,
|
||||||
input logic HWRITE,
|
input logic HWRITE,
|
||||||
input logic HREADY,
|
input logic HREADY,
|
||||||
input logic [1:0] HTRANS,
|
input logic [1:0] HTRANS,
|
||||||
input logic [`XLEN-1:0] HWDATA,
|
input logic [P.XLEN-1:0] HWDATA,
|
||||||
input logic [`XLEN/8-1:0] HWSTRB,
|
input logic [P.XLEN/8-1:0] HWSTRB,
|
||||||
output logic [`XLEN-1:0] HREADRam,
|
output logic [P.XLEN-1:0] HREADRam,
|
||||||
output logic HRESPRam, HREADYRam
|
output logic HRESPRam, HREADYRam
|
||||||
);
|
);
|
||||||
|
|
||||||
localparam ADDR_WIDTH = $clog2(RANGE/8);
|
localparam ADDR_WIDTH = $clog2(RANGE/8);
|
||||||
localparam OFFSET = $clog2(`XLEN/8);
|
localparam OFFSET = $clog2(P.XLEN/8);
|
||||||
|
|
||||||
logic [`XLEN/8-1:0] ByteMask;
|
logic [P.XLEN/8-1:0] ByteMask;
|
||||||
logic [`PA_BITS-1:0] HADDRD, RamAddr;
|
logic [P.PA_BITS-1:0] HADDRD, RamAddr;
|
||||||
logic initTrans;
|
logic initTrans;
|
||||||
logic memwrite, memwriteD, memread;
|
logic memwrite, memwriteD, memread;
|
||||||
logic nextHREADYRam;
|
logic nextHREADYRam;
|
||||||
@ -59,7 +58,7 @@ module ram_ahb #(parameter BASE=0, RANGE = 65535) (
|
|||||||
assign memread = initTrans & ~HWRITE;
|
assign memread = initTrans & ~HWRITE;
|
||||||
|
|
||||||
flopenr #(1) memwritereg(HCLK, ~HRESETn, HREADY, memwrite, memwriteD);
|
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
|
// Stall on a read after a write because the RAM can't take both adddresses on the same cycle
|
||||||
assign nextHREADYRam = (~(memwriteD & memread)) & ~DelayReady;
|
assign nextHREADYRam = (~(memwriteD & memread)) & ~DelayReady;
|
||||||
@ -68,10 +67,10 @@ module ram_ahb #(parameter BASE=0, RANGE = 65535) (
|
|||||||
assign HRESPRam = 0; // OK
|
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
|
// 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
|
// 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));
|
.addr(RamAddr[ADDR_WIDTH+OFFSET-1:OFFSET]), .we(memwriteD), .din(HWDATA), .bwe(HWSTRB), .dout(HREADRam));
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,27 +26,25 @@
|
|||||||
// and limitations under the License.
|
// and limitations under the License.
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
`include "wally-config.vh"
|
module rom_ahb import cvw::*; #(parameter cvw_t P, BASE=0, RANGE = 65535) (
|
||||||
|
|
||||||
module rom_ahb #(parameter BASE=0, RANGE = 65535) (
|
|
||||||
input logic HCLK, HRESETn,
|
input logic HCLK, HRESETn,
|
||||||
input logic HSELRom,
|
input logic HSELRom,
|
||||||
input logic [`PA_BITS-1:0] HADDR,
|
input logic [P.PA_BITS-1:0] HADDR,
|
||||||
input logic HREADY,
|
input logic HREADY,
|
||||||
input logic [1:0] HTRANS,
|
input logic [1:0] HTRANS,
|
||||||
output logic [`XLEN-1:0] HREADRom,
|
output logic [P.XLEN-1:0] HREADRom,
|
||||||
output logic HRESPRom, HREADYRom
|
output logic HRESPRom, HREADYRom
|
||||||
);
|
);
|
||||||
|
|
||||||
localparam ADDR_WIDTH = $clog2(RANGE/8);
|
localparam ADDR_WIDTH = $clog2(RANGE/8);
|
||||||
localparam OFFSET = $clog2(`XLEN/8);
|
localparam OFFSET = $clog2(P.XLEN/8);
|
||||||
|
|
||||||
// Never stalls
|
// Never stalls
|
||||||
assign HREADYRom = 1'b1;
|
assign HREADYRom = 1'b1;
|
||||||
assign HRESPRom = 0; // OK
|
assign HRESPRom = 0; // OK
|
||||||
|
|
||||||
// single-ported ROM
|
// 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));
|
memory(.clk(HCLK), .ce(1'b1), .addr(HADDR[ADDR_WIDTH+OFFSET-1:OFFSET]), .dout(HREADRom));
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
@ -33,10 +33,9 @@
|
|||||||
// and limitations under the License.
|
// and limitations under the License.
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
`include "wally-config.vh"
|
|
||||||
/* verilator lint_off UNOPTFLAT */
|
/* verilator lint_off UNOPTFLAT */
|
||||||
|
|
||||||
module uartPC16550D(
|
module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
|
||||||
// Processor Interface
|
// Processor Interface
|
||||||
input logic PCLK, PRESETn, // UART clock and active low reset
|
input logic PCLK, PRESETn, // UART clock and active low reset
|
||||||
input logic [2:0] A, // address input (8 registers)
|
input logic [2:0] A, // address input (8 registers)
|
||||||
@ -73,7 +72,7 @@ module uartPC16550D(
|
|||||||
|
|
||||||
// Baud and rx/tx timing
|
// Baud and rx/tx timing
|
||||||
logic baudpulse, txbaudpulse, rxbaudpulse; // high one system clk cycle each baud/16 period
|
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] rxoversampledcnt, txoversampledcnt; // count oversampled-by-16
|
||||||
logic [3:0] rxbitsreceived, txbitssent;
|
logic [3:0] rxbitsreceived, txbitssent;
|
||||||
statetype rxstate, txstate;
|
statetype rxstate, txstate;
|
||||||
@ -137,7 +136,7 @@ module uartPC16550D(
|
|||||||
if (~PRESETn) begin // Table 3 Reset Configuration
|
if (~PRESETn) begin // Table 3 Reset Configuration
|
||||||
IER <= #1 4'b0;
|
IER <= #1 4'b0;
|
||||||
FCR <= #1 8'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;
|
MCR <= #1 5'b0;
|
||||||
LSR <= #1 8'b01100000;
|
LSR <= #1 8'b01100000;
|
||||||
MSR <= #1 4'b0;
|
MSR <= #1 4'b0;
|
||||||
@ -225,7 +224,7 @@ module uartPC16550D(
|
|||||||
baudcount <= #1 baudpulseComb ? 1 : baudcount +1;
|
baudcount <= #1 baudpulseComb ? 1 : baudcount +1;
|
||||||
end
|
end
|
||||||
|
|
||||||
assign baudpulseComb = (baudcount == {DLM, DLL, {(`UART_PRESCALE){1'b0}}});
|
assign baudpulseComb = (baudcount == {DLM, DLL, {(UART_PRESCALE){1'b0}}});
|
||||||
|
|
||||||
assign txbaudpulse = baudpulse;
|
assign txbaudpulse = baudpulse;
|
||||||
assign BAUDOUTb = ~baudpulse;
|
assign BAUDOUTb = ~baudpulse;
|
||||||
@ -260,7 +259,7 @@ module uartPC16550D(
|
|||||||
end
|
end
|
||||||
|
|
||||||
// ***explain why
|
// ***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
|
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
|
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
|
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?
|
// *** 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
|
else assign txnextbit = txbaudpulse & (txoversampledcnt == 4'b0000); // implies txstate = UART_ACTIVE
|
||||||
|
|
||||||
///////////////////////////////////////////
|
///////////////////////////////////////////
|
||||||
|
@ -28,17 +28,15 @@
|
|||||||
// and limitations under the License.
|
// and limitations under the License.
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
`include "wally-config.vh"
|
module uart_apb import cvw::*; #(parameter cvw_t P) (
|
||||||
|
|
||||||
module uart_apb (
|
|
||||||
input logic PCLK, PRESETn,
|
input logic PCLK, PRESETn,
|
||||||
input logic PSEL,
|
input logic PSEL,
|
||||||
input logic [2:0] PADDR,
|
input logic [2:0] PADDR,
|
||||||
input logic [`XLEN-1:0] PWDATA,
|
input logic [P.XLEN-1:0] PWDATA,
|
||||||
input logic [`XLEN/8-1:0] PSTRB,
|
input logic [P.XLEN/8-1:0] PSTRB,
|
||||||
input logic PWRITE,
|
input logic PWRITE,
|
||||||
input logic PENABLE,
|
input logic PENABLE,
|
||||||
output logic [`XLEN-1:0] PRDATA,
|
output logic [P.XLEN-1:0] PRDATA,
|
||||||
output logic PREADY,
|
output logic PREADY,
|
||||||
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
|
||||||
@ -56,7 +54,7 @@ module uart_apb (
|
|||||||
assign MEMRb = ~memread;
|
assign MEMRb = ~memread;
|
||||||
assign MEMWb = ~memwrite;
|
assign MEMWb = ~memwrite;
|
||||||
|
|
||||||
if (`XLEN == 64) begin:uart
|
if (P.XLEN == 64) begin:uart
|
||||||
always_comb begin
|
always_comb begin
|
||||||
PRDATA = {Dout, Dout, Dout, Dout, Dout, Dout, Dout, Dout};
|
PRDATA = {Dout, Dout, Dout, Dout, Dout, Dout, Dout, Dout};
|
||||||
case (entry)
|
case (entry)
|
||||||
@ -84,7 +82,7 @@ module uart_apb (
|
|||||||
|
|
||||||
logic BAUDOUTb; // loop tx clock BAUDOUTb back to rx clock RCLK
|
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
|
// *** 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
|
// Processor Interface
|
||||||
.PCLK, .PRESETn,
|
.PCLK, .PRESETn,
|
||||||
.A(entry), .Din,
|
.A(entry), .Din,
|
||||||
|
@ -27,24 +27,22 @@
|
|||||||
// and limitations under the License.
|
// and limitations under the License.
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
`include "wally-config.vh"
|
|
||||||
|
|
||||||
module uncore import cvw::*; #(parameter cvw_t P)(
|
module uncore import cvw::*; #(parameter cvw_t P)(
|
||||||
// AHB Bus Interface
|
// AHB Bus Interface
|
||||||
input logic HCLK, HRESETn,
|
input logic HCLK, HRESETn,
|
||||||
input logic TIMECLK,
|
input logic TIMECLK,
|
||||||
input logic [`PA_BITS-1:0] HADDR,
|
input logic [P.PA_BITS-1:0] HADDR,
|
||||||
input logic [`AHBW-1:0] HWDATA,
|
input logic [P.AHBW-1:0] HWDATA,
|
||||||
input logic [`XLEN/8-1:0] HWSTRB,
|
input logic [P.XLEN/8-1:0] HWSTRB,
|
||||||
input logic HWRITE,
|
input logic HWRITE,
|
||||||
input logic [2:0] HSIZE,
|
input logic [2:0] HSIZE,
|
||||||
input logic [2:0] HBURST,
|
input logic [2:0] HBURST,
|
||||||
input logic [3:0] HPROT,
|
input logic [3:0] HPROT,
|
||||||
input logic [1:0] HTRANS,
|
input logic [1:0] HTRANS,
|
||||||
input logic HMASTLOCK,
|
input logic HMASTLOCK,
|
||||||
input logic [`AHBW-1:0] HRDATAEXT,
|
input logic [P.AHBW-1:0] HRDATAEXT,
|
||||||
input logic HREADYEXT, HRESPEXT,
|
input logic HREADYEXT, HRESPEXT,
|
||||||
output logic [`AHBW-1:0] HRDATA,
|
output logic [P.AHBW-1:0] HRDATA,
|
||||||
output logic HREADY, HRESP,
|
output logic HREADY, HRESP,
|
||||||
output logic HSELEXT,
|
output logic HSELEXT,
|
||||||
// peripheral pins
|
// peripheral pins
|
||||||
@ -62,14 +60,14 @@ module uncore import cvw::*; #(parameter cvw_t P)(
|
|||||||
output logic SDCCLK // SD Card clock
|
output logic SDCCLK // SD Card clock
|
||||||
);
|
);
|
||||||
|
|
||||||
logic [`XLEN-1:0] HREADRam, HREADSDC;
|
logic [P.XLEN-1:0] HREADRam, HREADSDC;
|
||||||
|
|
||||||
logic [10:0] HSELRegions;
|
logic [10:0] HSELRegions;
|
||||||
logic HSELDTIM, HSELIROM, HSELRam, HSELCLINT, HSELPLIC, HSELGPIO, HSELUART, HSELSDC;
|
logic HSELDTIM, HSELIROM, HSELRam, HSELCLINT, HSELPLIC, HSELGPIO, HSELUART, HSELSDC;
|
||||||
logic HSELDTIMD, HSELIROMD, HSELEXTD, HSELRamD, HSELCLINTD, HSELPLICD, HSELGPIOD, HSELUARTD, HSELSDCD;
|
logic HSELDTIMD, HSELIROMD, HSELEXTD, HSELRamD, HSELCLINTD, HSELPLICD, HSELGPIOD, HSELUARTD, HSELSDCD;
|
||||||
logic HRESPRam, HRESPSDC;
|
logic HRESPRam, HRESPSDC;
|
||||||
logic HREADYRam, HRESPSDCD;
|
logic HREADYRam, HRESPSDCD;
|
||||||
logic [`XLEN-1:0] HREADBootRom;
|
logic [P.XLEN-1:0] HREADBootRom;
|
||||||
logic HSELBootRom, HSELBootRomD, HRESPBootRom, HREADYBootRom, HREADYSDC;
|
logic HSELBootRom, HSELBootRomD, HRESPBootRom, HREADYBootRom, HREADYSDC;
|
||||||
logic HSELNoneD;
|
logic HSELNoneD;
|
||||||
logic UARTIntr,GPIOIntr;
|
logic UARTIntr,GPIOIntr;
|
||||||
@ -78,10 +76,10 @@ module uncore import cvw::*; #(parameter cvw_t P)(
|
|||||||
logic PCLK, PRESETn, PWRITE, PENABLE;
|
logic PCLK, PRESETn, PWRITE, PENABLE;
|
||||||
logic [3:0] PSEL, PREADY;
|
logic [3:0] PSEL, PREADY;
|
||||||
logic [31:0] PADDR;
|
logic [31:0] PADDR;
|
||||||
logic [`XLEN-1:0] PWDATA;
|
logic [P.XLEN-1:0] PWDATA;
|
||||||
logic [`XLEN/8-1:0] PSTRB;
|
logic [P.XLEN/8-1:0] PSTRB;
|
||||||
logic [3:0][`XLEN-1:0] PRDATA;
|
logic [3:0][P.XLEN-1:0] PRDATA;
|
||||||
logic [`XLEN-1:0] HREADBRIDGE;
|
logic [P.XLEN-1:0] HREADBRIDGE;
|
||||||
logic HRESPBRIDGE, HREADYBRIDGE, HSELBRIDGE, HSELBRIDGED;
|
logic HRESPBRIDGE, HREADYBRIDGE, HSELBRIDGE, HSELBRIDGED;
|
||||||
|
|
||||||
// Determine which region of physical memory (if any) is being accessed
|
// 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];
|
assign {HSELDTIM, HSELIROM, HSELEXT, HSELBootRom, HSELRam, HSELCLINT, HSELGPIO, HSELUART, HSELPLIC, HSELSDC} = HSELRegions[10:1];
|
||||||
|
|
||||||
// AHB -> APB bridge
|
// AHB -> APB bridge
|
||||||
ahbapbbridge #(4) ahbapbbridge (
|
ahbapbbridge #(P, 4) ahbapbbridge (
|
||||||
.HCLK, .HRESETn, .HSEL({HSELUART, HSELPLIC, HSELCLINT, HSELGPIO}), .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HTRANS, .HREADY,
|
.HCLK, .HRESETn, .HSEL({HSELUART, HSELPLIC, HSELCLINT, HSELGPIO}), .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HTRANS, .HREADY,
|
||||||
.HRDATA(HREADBRIDGE), .HRESP(HRESPBRIDGE), .HREADYOUT(HREADYBRIDGE),
|
.HRDATA(HREADBRIDGE), .HRESP(HRESPBRIDGE), .HREADYOUT(HREADYBRIDGE),
|
||||||
.PCLK, .PRESETn, .PSEL, .PWRITE, .PENABLE, .PADDR, .PWDATA, .PSTRB, .PREADY, .PRDATA);
|
.PCLK, .PRESETn, .PSEL, .PWRITE, .PENABLE, .PADDR, .PWDATA, .PSTRB, .PREADY, .PRDATA);
|
||||||
assign HSELBRIDGE = HSELGPIO | HSELCLINT | HSELPLIC | HSELUART; // if any of the bridge signals are selected
|
assign HSELBRIDGE = HSELGPIO | HSELCLINT | HSELPLIC | HSELUART; // if any of the bridge signals are selected
|
||||||
|
|
||||||
// on-chip RAM
|
// on-chip RAM
|
||||||
if (`UNCORE_RAM_SUPPORTED) begin : ram
|
if (P.UNCORE_RAM_SUPPORTED) begin : ram
|
||||||
ram_ahb #(.BASE(`UNCORE_RAM_BASE), .RANGE(`UNCORE_RAM_RANGE)) ram (
|
ram_ahb #(.P(P), .BASE(P.UNCORE_RAM_BASE), .RANGE(P.UNCORE_RAM_RANGE)) ram (
|
||||||
.HCLK, .HRESETn, .HSELRam, .HADDR, .HWRITE, .HREADY,
|
.HCLK, .HRESETn, .HSELRam, .HADDR, .HWRITE, .HREADY,
|
||||||
.HTRANS, .HWDATA, .HWSTRB, .HREADRam, .HRESPRam, .HREADYRam);
|
.HTRANS, .HWDATA, .HWSTRB, .HREADRam, .HRESPRam, .HREADYRam);
|
||||||
end
|
end
|
||||||
|
|
||||||
if (`BOOTROM_SUPPORTED) begin : bootrom
|
if (P.BOOTROM_SUPPORTED) begin : bootrom
|
||||||
rom_ahb #(.BASE(`BOOTROM_BASE), .RANGE(`BOOTROM_RANGE))
|
rom_ahb #(.P(P), .BASE(P.BOOTROM_BASE), .RANGE(P.BOOTROM_RANGE))
|
||||||
bootrom(.HCLK, .HRESETn, .HSELRom(HSELBootRom), .HADDR, .HREADY, .HTRANS,
|
bootrom(.HCLK, .HRESETn, .HSELRom(HSELBootRom), .HADDR, .HREADY, .HTRANS,
|
||||||
.HREADRom(HREADBootRom), .HRESPRom(HRESPBootRom), .HREADYRom(HREADYBootRom));
|
.HREADRom(HREADBootRom), .HRESPRom(HRESPBootRom), .HREADYRom(HREADYBootRom));
|
||||||
end
|
end
|
||||||
|
|
||||||
// memory-mapped I/O peripherals
|
// memory-mapped I/O peripherals
|
||||||
if (`CLINT_SUPPORTED == 1) begin : clint
|
if (P.CLINT_SUPPORTED == 1) begin : clint
|
||||||
clint_apb clint(.PCLK, .PRESETn, .PSEL(PSEL[1]), .PADDR(PADDR[15:0]), .PWDATA, .PSTRB, .PWRITE, .PENABLE,
|
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);
|
.PRDATA(PRDATA[1]), .PREADY(PREADY[1]), .MTIME(MTIME_CLINT), .MTimerInt, .MSwInt);
|
||||||
end else begin : clint
|
end else begin : clint
|
||||||
assign MTIME_CLINT = 0;
|
assign MTIME_CLINT = 0;
|
||||||
assign MTimerInt = 0; assign MSwInt = 0;
|
assign MTimerInt = 0; assign MSwInt = 0;
|
||||||
end
|
end
|
||||||
|
|
||||||
if (`PLIC_SUPPORTED == 1) begin : plic
|
if (P.PLIC_SUPPORTED == 1) begin : plic
|
||||||
plic_apb plic(.PCLK, .PRESETn, .PSEL(PSEL[2]), .PADDR(PADDR[27:0]), .PWDATA, .PSTRB, .PWRITE, .PENABLE,
|
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);
|
.PRDATA(PRDATA[2]), .PREADY(PREADY[2]), .UARTIntr, .GPIOIntr, .MExtInt, .SExtInt);
|
||||||
end else begin : plic
|
end else begin : plic
|
||||||
assign MExtInt = 0;
|
assign MExtInt = 0;
|
||||||
assign SExtInt = 0;
|
assign SExtInt = 0;
|
||||||
end
|
end
|
||||||
|
|
||||||
if (`GPIO_SUPPORTED == 1) begin : gpio
|
if (P.GPIO_SUPPORTED == 1) begin : gpio
|
||||||
gpio_apb gpio(
|
gpio_apb #(P) gpio(
|
||||||
.PCLK, .PRESETn, .PSEL(PSEL[0]), .PADDR(PADDR[7:0]), .PWDATA, .PSTRB, .PWRITE, .PENABLE,
|
.PCLK, .PRESETn, .PSEL(PSEL[0]), .PADDR(PADDR[7:0]), .PWDATA, .PSTRB, .PWRITE, .PENABLE,
|
||||||
.PRDATA(PRDATA[0]), .PREADY(PREADY[0]),
|
.PRDATA(PRDATA[0]), .PREADY(PREADY[0]),
|
||||||
.iof0(), .iof1(), .GPIOIN, .GPIOOUT, .GPIOEN, .GPIOIntr);
|
.iof0(), .iof1(), .GPIOIN, .GPIOOUT, .GPIOEN, .GPIOIntr);
|
||||||
end else begin : gpio
|
end else begin : gpio
|
||||||
assign GPIOOUT = 0; assign GPIOEN = 0; assign GPIOIntr = 0;
|
assign GPIOOUT = 0; assign GPIOEN = 0; assign GPIOIntr = 0;
|
||||||
end
|
end
|
||||||
if (`UART_SUPPORTED == 1) begin : uart
|
if (P.UART_SUPPORTED == 1) begin : uart
|
||||||
uart_apb uart(
|
uart_apb #(P) uart(
|
||||||
.PCLK, .PRESETn, .PSEL(PSEL[3]), .PADDR(PADDR[2:0]), .PWDATA, .PSTRB, .PWRITE, .PENABLE,
|
.PCLK, .PRESETn, .PSEL(PSEL[3]), .PADDR(PADDR[2:0]), .PWDATA, .PSTRB, .PWRITE, .PENABLE,
|
||||||
.PRDATA(PRDATA[3]), .PREADY(PREADY[3]),
|
.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
|
.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
|
end else begin : uart
|
||||||
assign UARTSout = 0; assign UARTIntr = 0;
|
assign UARTSout = 0; assign UARTIntr = 0;
|
||||||
end
|
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,
|
SDC SDC(.HCLK, .HRESETn, .HSELSDC, .HADDR(HADDR[4:0]), .HWRITE, .HREADY, .HTRANS,
|
||||||
.HWDATA, .HREADSDC, .HRESPSDC, .HREADYSDC,
|
.HWDATA, .HREADSDC, .HRESPSDC, .HREADYSDC,
|
||||||
// sdc interface
|
// sdc interface
|
||||||
@ -162,11 +160,11 @@ module uncore import cvw::*; #(parameter cvw_t P)(
|
|||||||
end
|
end
|
||||||
|
|
||||||
// AHB Read Multiplexer
|
// AHB Read Multiplexer
|
||||||
assign HRDATA = ({`XLEN{HSELRamD}} & HREADRam) |
|
assign HRDATA = ({P.XLEN{HSELRamD}} & HREADRam) |
|
||||||
({`XLEN{HSELEXTD}} & HRDATAEXT) |
|
({P.XLEN{HSELEXTD}} & HRDATAEXT) |
|
||||||
({`XLEN{HSELBRIDGED}} & HREADBRIDGE) |
|
({P.XLEN{HSELBRIDGED}} & HREADBRIDGE) |
|
||||||
({`XLEN{HSELBootRomD}} & HREADBootRom) |
|
({P.XLEN{HSELBootRomD}} & HREADBootRom) |
|
||||||
({`XLEN{HSELSDCD}} & HREADSDC);
|
({P.XLEN{HSELSDCD}} & HREADSDC);
|
||||||
|
|
||||||
assign HRESP = HSELRamD & HRESPRam |
|
assign HRESP = HSELRamD & HRESPRam |
|
||||||
HSELEXTD & HRESPEXT |
|
HSELEXTD & HRESPEXT |
|
||||||
|
Loading…
Reference in New Issue
Block a user