mirror of
https://github.com/openhwgroup/cvw.git
synced 2025-04-24 13:57:07 -04:00
Started adding asynchronous TIMECLK for CLINT
This commit is contained in:
parent
9d4e1671c9
commit
9693110857
12 changed files with 169 additions and 54 deletions
|
@ -1 +1 @@
|
||||||
Subproject commit be67c99bd461742aa1c100bcc0732657faae2230
|
Subproject commit 307c77b26e070ae85ffea665ad9b642b40e33c86
|
|
@ -29,8 +29,8 @@
|
||||||
|
|
||||||
rv32i_sc_tests = \
|
rv32i_sc_tests = \
|
||||||
WALLY-MMU-SV32 \
|
WALLY-MMU-SV32 \
|
||||||
WALLY-PMA \
|
|
||||||
WALLY-PMP
|
WALLY-PMP
|
||||||
|
# WALLY-PMA \
|
||||||
|
|
||||||
rv32i_tests = $(addsuffix .elf, $(rv32i_sc_tests))
|
rv32i_tests = $(addsuffix .elf, $(rv32i_sc_tests))
|
||||||
|
|
||||||
|
|
|
@ -30,8 +30,8 @@
|
||||||
rv64i_sc_tests = \
|
rv64i_sc_tests = \
|
||||||
WALLY-MMU-SV39 \
|
WALLY-MMU-SV39 \
|
||||||
WALLY-MMU-SV48 \
|
WALLY-MMU-SV48 \
|
||||||
WALLY-PMA \
|
# WALLY-PMP
|
||||||
WALLY-PMP
|
# WALLY-PMA \
|
||||||
|
|
||||||
|
|
||||||
rv64i_tests = $(addsuffix .elf, $(rv64i_sc_tests))
|
rv64i_tests = $(addsuffix .elf, $(rv64i_sc_tests))
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
module csrc #(parameter
|
module csrc #(parameter
|
||||||
MHPMCOUNTERBASE = 12'hB00,
|
MHPMCOUNTERBASE = 12'hB00,
|
||||||
MHPMCOUNTERHBASE = 12'hB80,
|
MHPMCOUNTERHBASE = 12'hB80,
|
||||||
|
MHPMEVENTBASE = 12'h320,
|
||||||
HPMCOUNTERBASE = 12'hC00,
|
HPMCOUNTERBASE = 12'hC00,
|
||||||
HPMCOUNTERHBASE = 12'hC80,
|
HPMCOUNTERHBASE = 12'hC80,
|
||||||
TIME = 12'hC01,
|
TIME = 12'hC01,
|
||||||
|
@ -162,3 +163,8 @@ module csrc #(parameter
|
||||||
endgenerate
|
endgenerate
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
// To Do:
|
||||||
|
// review couunter spec
|
||||||
|
// upper unimplemented counters should read as 0 rather than illegal access
|
||||||
|
// mounteren should only exist if u-mode exists
|
||||||
|
// Implement MHPMEVENT
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
`include "wally-config.vh"
|
`include "wally-config.vh"
|
||||||
|
|
||||||
module clint (
|
module clint (
|
||||||
input logic HCLK, HRESETn,
|
input logic HCLK, HRESETn, TIMECLK,
|
||||||
input logic HSELCLINT,
|
input logic HSELCLINT,
|
||||||
input logic [15:0] HADDR,
|
input logic [15:0] HADDR,
|
||||||
input logic HWRITE,
|
input logic HWRITE,
|
||||||
|
@ -52,7 +52,7 @@ module clint (
|
||||||
flopr #(16) entrydflop(HCLK, ~HRESETn, entry, entryd);
|
flopr #(16) entrydflop(HCLK, ~HRESETn, entry, entryd);
|
||||||
|
|
||||||
assign HRESPCLINT = 0; // OK
|
assign HRESPCLINT = 0; // OK
|
||||||
assign HREADYCLINT = 1'b1; // will need to be modified if CLINT ever needs more than 1 cycle to do something
|
assign HREADYCLINT = 1'b1; // *** needs to depend on DONE during accesses
|
||||||
|
|
||||||
// word aligned reads
|
// word aligned reads
|
||||||
generate
|
generate
|
||||||
|
@ -70,7 +70,7 @@ module clint (
|
||||||
|
|
||||||
// register access
|
// register access
|
||||||
generate
|
generate
|
||||||
if (`XLEN==64) begin:clint
|
if (`XLEN==64) begin:clint // 64-bit
|
||||||
always @(posedge HCLK) begin
|
always @(posedge HCLK) begin
|
||||||
case(entry)
|
case(entry)
|
||||||
16'h0000: HREADCLINT <= {63'b0, MSIP};
|
16'h0000: HREADCLINT <= {63'b0, MSIP};
|
||||||
|
@ -82,22 +82,24 @@ module clint (
|
||||||
always_ff @(posedge HCLK or negedge HRESETn)
|
always_ff @(posedge HCLK or negedge HRESETn)
|
||||||
if (~HRESETn) begin
|
if (~HRESETn) begin
|
||||||
MSIP <= 0;
|
MSIP <= 0;
|
||||||
MTIMECMP <= (64)'(0);
|
MTIMECMP <= 0;
|
||||||
// MTIMECMP is not reset
|
// MTIMECMP is not reset
|
||||||
end else if (memwrite) begin
|
end else if (memwrite) begin
|
||||||
if (entryd == 16'h0000) MSIP <= HWDATA[0];
|
if (entryd == 16'h0000) MSIP <= HWDATA[0];
|
||||||
if (entryd == 16'h4000) MTIMECMP <= HWDATA;
|
if (entryd == 16'h4000) MTIMECMP <= HWDATA;
|
||||||
// MTIME Counter. Eventually change this to run off separate clock. Synchronization then needed
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
// eventually replace MTIME logic below with timereg
|
||||||
|
// timereg tr(HCLK, HRESETn, TIMECLK, memwrite & (entryd==16'hBFF8), 1'b0, HWDATA, MTIME, done);
|
||||||
|
|
||||||
always_ff @(posedge HCLK or negedge HRESETn)
|
always_ff @(posedge HCLK or negedge HRESETn)
|
||||||
if (~HRESETn) begin
|
if (~HRESETn) begin
|
||||||
MTIME <= 0;
|
MTIME <= 0;
|
||||||
// MTIMECMP is not reset
|
// MTIMECMP is not reset
|
||||||
end else if (memwrite & entryd == 16'hBFF8) begin
|
end else if (memwrite & entryd == 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
|
||||||
MTIME <= HWDATA;
|
MTIME <= HWDATA;
|
||||||
end else MTIME <= MTIME + 1;
|
end else MTIME <= MTIME + 1;
|
||||||
end else begin:clint // 32-bit
|
end else begin:clint // 32-bit
|
||||||
always @(posedge HCLK) begin
|
always @(posedge HCLK) begin
|
||||||
case(entry)
|
case(entry)
|
||||||
|
@ -112,26 +114,28 @@ module clint (
|
||||||
always_ff @(posedge HCLK or negedge HRESETn)
|
always_ff @(posedge HCLK or negedge HRESETn)
|
||||||
if (~HRESETn) begin
|
if (~HRESETn) begin
|
||||||
MSIP <= 0;
|
MSIP <= 0;
|
||||||
MTIMECMP <= (64)'(0);
|
MTIMECMP <= 0;
|
||||||
// MTIMECMP is not reset
|
// MTIMECMP is not reset ***?
|
||||||
end else if (memwrite) begin
|
end else if (memwrite) begin
|
||||||
if (entryd == 16'h0000) MSIP <= HWDATA[0];
|
if (entryd == 16'h0000) MSIP <= HWDATA[0];
|
||||||
if (entryd == 16'h4000) MTIMECMP[31:0] <= HWDATA;
|
if (entryd == 16'h4000) MTIMECMP[31:0] <= HWDATA;
|
||||||
if (entryd == 16'h4004) MTIMECMP[63:32] <= HWDATA;
|
if (entryd == 16'h4004) MTIMECMP[63:32] <= HWDATA;
|
||||||
// MTIME Counter. Eventually change this to run off separate clock. Synchronization then needed
|
// MTIME Counter. Eventually change this to run off separate clock. Synchronization then needed
|
||||||
end
|
end
|
||||||
|
|
||||||
|
// eventually replace MTIME logic below with timereg
|
||||||
|
// timereg tr(HCLK, HRESETn, TIMECLK, memwrite & (entryd==16'hBFF8), memwrite & (entryd == 16'hBFFC), HWDATA, MTIME, done);
|
||||||
always_ff @(posedge HCLK or negedge HRESETn)
|
always_ff @(posedge HCLK or negedge HRESETn)
|
||||||
if (~HRESETn) begin
|
if (~HRESETn) begin
|
||||||
MTIME <= 0;
|
MTIME <= 0;
|
||||||
// MTIMECMP is not reset
|
// MTIMECMP is not reset
|
||||||
end else if (memwrite & (entryd == 16'hBFF8)) begin
|
end else if (memwrite & (entryd == 16'hBFF8)) begin
|
||||||
MTIME[31:0] <= HWDATA;
|
MTIME[31:0] <= HWDATA;
|
||||||
end else if (memwrite & (entryd == 16'hBFFC)) begin
|
end else if (memwrite & (entryd == 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
|
||||||
MTIME[63:32]<= HWDATA;
|
MTIME[63:32]<= HWDATA;
|
||||||
end else MTIME <= MTIME + 1;
|
end else MTIME <= MTIME + 1;
|
||||||
end
|
end
|
||||||
endgenerate
|
endgenerate
|
||||||
|
|
||||||
// Software interrupt when MSIP is set
|
// Software interrupt when MSIP is set
|
||||||
|
@ -141,3 +145,102 @@ module clint (
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
module timeregsync(
|
||||||
|
input logic clk, resetn,
|
||||||
|
input logic we0, we1,
|
||||||
|
input logic [`XLEN-1:0] wd,
|
||||||
|
output logic [63:0] q);
|
||||||
|
|
||||||
|
if (`XLEN==64)
|
||||||
|
always_ff @(posedge clk or negedge resetn)
|
||||||
|
if (~resetn) q <= 0;
|
||||||
|
else if (we0) q <= wd;
|
||||||
|
else q <= q + 1;
|
||||||
|
else
|
||||||
|
always_ff @(posedge clk or negedge resetn)
|
||||||
|
if (~resetn) q <= 0;
|
||||||
|
else if (we0) q[31:0] <= wd;
|
||||||
|
else if (we1) q[63:32] <= wd;
|
||||||
|
else q <= q + 1;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module timereg(
|
||||||
|
input logic HCLK, HRESETn, TIMECLK,
|
||||||
|
input logic we0, we1,
|
||||||
|
input logic [`XLEN-1:0] HWDATA,
|
||||||
|
output logic [63:0] MTIME,
|
||||||
|
output logic done);
|
||||||
|
|
||||||
|
// if (`TIMEBASE_SYNC) begin:timereg // use HCLK for MTIME
|
||||||
|
if (1) begin:timereg // use HCLK for MTIME
|
||||||
|
timregsync timeregsync(.clk(HCLK), .resetn(HRESETn), .we0, .we1, .wd(HWDATA), .q(MTIME));
|
||||||
|
assign done = 1; // immediately completes
|
||||||
|
end else begin // use asynchronous TIMECLK
|
||||||
|
// TIME counter runs on TIMECLK but bus interface runs on HCLK
|
||||||
|
// Need to synchronize reads and writes
|
||||||
|
// This is subtle because synchronizing a binary counter on a per-bit basis could give a mix of old and new bits
|
||||||
|
// Instead, we use a Gray coded counter that only changes one bit per cycle
|
||||||
|
// Synchronizing this for a read is safe because we are guaranteed to get either the old or the new value.
|
||||||
|
// Writing to the counter requires a request/acknowledge handshake to ensure the write value is held long enough.
|
||||||
|
// The handshake signals are synchronized in each direction across the interface
|
||||||
|
// 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 [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 the acknowledge falls, the transaction is done and the system is ready for another write.
|
||||||
|
// ***look at redoing this assuming write enable and data are held rather than pulsed.
|
||||||
|
always_ff @(posedge HCLK or negedge HRESETn)
|
||||||
|
if (~HRESETn)
|
||||||
|
req <= 0; // don't bother resetting wd
|
||||||
|
else begin
|
||||||
|
req <= we0 | we1 | req & ~ack;
|
||||||
|
we0_stored <= we0;
|
||||||
|
we1_stored <= we1;
|
||||||
|
wd_stored <= HWDATA;
|
||||||
|
ack_stored <= ack;
|
||||||
|
done <= ack_stored & ~ack;
|
||||||
|
end
|
||||||
|
|
||||||
|
// synchronize the reset and reqest into the TIMECLK domain
|
||||||
|
sync resetsync(TIMECLK, HRESETn, resetn_sync);
|
||||||
|
sync rsync(TIMECLK, req, req_sync);
|
||||||
|
// synchronize the acknowledge back to the HCLK domain to indicate the request was handled and can be lowered
|
||||||
|
sync async(HCLK, req_sync, ack);
|
||||||
|
|
||||||
|
timeregsync 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);
|
||||||
|
|
||||||
|
sync timesync[63:0](HCLK, time_gc, MTIME_GC);
|
||||||
|
graytobinary g2b(MTIME_GC, MTIME);
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module binarytogray #(parameter N = `XLEN) (
|
||||||
|
input logic [N-1:0] b,
|
||||||
|
output logic [N-1:0] g);
|
||||||
|
|
||||||
|
// G[N-1] = B[N-1]; G[i] = B[i] ^ B[i+1] for 0 <= i < N-1
|
||||||
|
// requires single layer of N-1 XOR gates
|
||||||
|
assign g = b ^ {1'b0, b[N-1:1]};
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module graytobinary #(parameter N = `XLEN) (
|
||||||
|
input logic [N-1:0] g,
|
||||||
|
output logic [N-1:0] b);
|
||||||
|
|
||||||
|
// B[N-1] = G[N-1]; B[i] = G[i] ^ B[i+1] for 0 <= i < N-1
|
||||||
|
// requires rippling through N-1 XOR gates
|
||||||
|
generate
|
||||||
|
begin
|
||||||
|
genvar i;
|
||||||
|
assign b[N-1] = g[N-1];
|
||||||
|
for (i=N-2; i >= 0; i--) begin:g2b
|
||||||
|
assign b[i] = g[i] ^ b[i+1];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
endmodule
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
module uncore (
|
module uncore (
|
||||||
// AHB Bus Interface
|
// AHB Bus Interface
|
||||||
input logic HCLK, HRESETn,
|
input logic HCLK, HRESETn,
|
||||||
|
input logic TIMECLK,
|
||||||
input logic [31:0] HADDR,
|
input logic [31:0] HADDR,
|
||||||
input logic [`AHBW-1:0] HWDATAIN,
|
input logic [`AHBW-1:0] HWDATAIN,
|
||||||
input logic HWRITE,
|
input logic HWRITE,
|
||||||
|
@ -115,7 +116,7 @@ module uncore (
|
||||||
// memory-mapped I/O peripherals
|
// memory-mapped I/O peripherals
|
||||||
if (`CLINT_SUPPORTED == 1) begin : clint
|
if (`CLINT_SUPPORTED == 1) begin : clint
|
||||||
clint clint(
|
clint clint(
|
||||||
.HCLK, .HRESETn,
|
.HCLK, .HRESETn, .TIMECLK,
|
||||||
.HSELCLINT, .HADDR(HADDR[15:0]), .HWRITE,
|
.HSELCLINT, .HADDR(HADDR[15:0]), .HWRITE,
|
||||||
.HWDATA, .HREADY, .HTRANS,
|
.HWDATA, .HREADY, .HTRANS,
|
||||||
.HREADCLINT,
|
.HREADCLINT,
|
||||||
|
|
|
@ -51,6 +51,7 @@ module wallypipelinedsoc (
|
||||||
output logic HMASTLOCK,
|
output logic HMASTLOCK,
|
||||||
output logic HREADY,
|
output logic HREADY,
|
||||||
// I/O Interface
|
// I/O Interface
|
||||||
|
input logic TIMECLK,
|
||||||
input logic [31:0] GPIOPinsIn,
|
input logic [31:0] GPIOPinsIn,
|
||||||
output logic [31:0] GPIOPinsOut, GPIOPinsEn,
|
output logic [31:0] GPIOPinsOut, GPIOPinsEn,
|
||||||
input logic UARTSin,
|
input logic UARTSin,
|
||||||
|
@ -85,7 +86,7 @@ module wallypipelinedsoc (
|
||||||
.HADDRD, .HSIZED, .HWRITED
|
.HADDRD, .HSIZED, .HWRITED
|
||||||
);
|
);
|
||||||
|
|
||||||
uncore uncore(.HCLK, .HRESETn,
|
uncore uncore(.HCLK, .HRESETn, .TIMECLK,
|
||||||
.HADDR, .HWDATAIN(HWDATA), .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, .HRDATAEXT,
|
.HADDR, .HWDATAIN(HWDATA), .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, .HRDATAEXT,
|
||||||
.HREADYEXT, .HRESPEXT, .HRDATA, .HREADY, .HRESP, .HADDRD, .HSIZED, .HWRITED,
|
.HREADYEXT, .HRESPEXT, .HRDATA, .HREADY, .HRESP, .HADDRD, .HSIZED, .HWRITED,
|
||||||
.TimerIntM, .SwIntM, .ExtIntM, .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn, .UARTSin, .UARTSout, .MTIME_CLINT,
|
.TimerIntM, .SwIntM, .ExtIntM, .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn, .UARTSin, .UARTSout, .MTIME_CLINT,
|
||||||
|
|
|
@ -50,6 +50,7 @@ module wallypipelinedsocwrapper (
|
||||||
output HMASTLOCK,
|
output HMASTLOCK,
|
||||||
output HREADY,
|
output HREADY,
|
||||||
// I/O Interface
|
// I/O Interface
|
||||||
|
input TIMECLK,
|
||||||
input [3:0] GPIOPinsIn_IO,
|
input [3:0] GPIOPinsIn_IO,
|
||||||
output [4:0] GPIOPinsOut_IO,
|
output [4:0] GPIOPinsOut_IO,
|
||||||
input UARTSin,
|
input UARTSin,
|
||||||
|
@ -89,32 +90,33 @@ module wallypipelinedsocwrapper (
|
||||||
|
|
||||||
// wrapper for fpga
|
// wrapper for fpga
|
||||||
wallypipelinedsoc wallypipelinedsoc
|
wallypipelinedsoc wallypipelinedsoc
|
||||||
(.clk(clk),
|
(.clk,
|
||||||
.reset_ext(reset),
|
.reset_ext(reset),
|
||||||
.HRDATAEXT(HRDATAEXT),
|
.HRDATAEXT,
|
||||||
.HREADYEXT(HREADYEXT),
|
.HREADYEXT,
|
||||||
.HRESPEXT(HRESPEXT),
|
.HRESPEXT,
|
||||||
.HSELEXT(HSELEXT),
|
.HSELEXT,
|
||||||
.HCLK(HCLK),
|
.HCLK,
|
||||||
.HRESETn(HRESETn),
|
.HRESETn,
|
||||||
.HADDR(HADDR),
|
.HADDR,
|
||||||
.HWDATA(HWDATA),
|
.HWDATA,
|
||||||
.HWRITE(HWRITE),
|
.HWRITE,
|
||||||
.HSIZE(HSIZE),
|
.HSIZE,
|
||||||
.HBURST(HBURST),
|
.HBURST,
|
||||||
.HPROT(HPROT),
|
.HPROT,
|
||||||
.HTRANS(HTRANS),
|
.HTRANS,
|
||||||
.HMASTLOCK(HMASTLOCK),
|
.HMASTLOCK,
|
||||||
.HREADY(HREADY),
|
.HREADY,
|
||||||
.GPIOPinsIn(GPIOPinsIn),
|
.TIMECLK,
|
||||||
.GPIOPinsOut(GPIOPinsOut),
|
.GPIOPinsIn,
|
||||||
.GPIOPinsEn(GPIOPinsEn),
|
.GPIOPinsOut,
|
||||||
.UARTSin(UARTSin),
|
.GPIOPinsEn,
|
||||||
.UARTSout(UARTSout),
|
.UARTSin,
|
||||||
.SDCDatIn(SDCDatIn),
|
.UARTSout,
|
||||||
.SDCCLK(SDCCLK),
|
.SDCDatIn,
|
||||||
.SDCCmdIn(SDCCmdIn),
|
.SDCCLK,
|
||||||
.SDCCmdOut(SDCCmdOut),
|
.SDCCmdIn,
|
||||||
.SDCCmdOE(SDCCmdOE));
|
.SDCCmdOut,
|
||||||
|
.SDCCmdOE);
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
|
@ -74,7 +74,7 @@ module testbench();
|
||||||
assign HRDATAEXT = 0;
|
assign HRDATAEXT = 0;
|
||||||
wallypipelinedsoc dut(.clk, .reset_ext, .HRDATAEXT,.HREADYEXT, .HRESPEXT,.HSELEXT,
|
wallypipelinedsoc dut(.clk, .reset_ext, .HRDATAEXT,.HREADYEXT, .HRESPEXT,.HSELEXT,
|
||||||
.HCLK, .HRESETn, .HADDR, .HWDATA, .HWRITE, .HSIZE, .HBURST, .HPROT,
|
.HCLK, .HRESETn, .HADDR, .HWDATA, .HWRITE, .HSIZE, .HBURST, .HPROT,
|
||||||
.HTRANS, .HMASTLOCK, .HREADY, .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn,
|
.HTRANS, .HMASTLOCK, .HREADY, .TIMECLK(0), .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn,
|
||||||
.UARTSin, .UARTSout, .SDCCmdIn, .SDCCmdOut, .SDCCmdOE, .SDCDatIn, .SDCCLK);
|
.UARTSin, .UARTSout, .SDCCmdIn, .SDCCmdOut, .SDCCmdOE, .SDCDatIn, .SDCCLK);
|
||||||
|
|
||||||
logic [31:0] InstrW;
|
logic [31:0] InstrW;
|
||||||
|
|
|
@ -602,7 +602,7 @@ string tests32f[] = '{
|
||||||
|
|
||||||
wallypipelinedsocwrapper dut(.clk, .reset_ext, .HRDATAEXT,.HREADYEXT, .HRESPEXT,.HSELEXT,
|
wallypipelinedsocwrapper dut(.clk, .reset_ext, .HRDATAEXT,.HREADYEXT, .HRESPEXT,.HSELEXT,
|
||||||
.HCLK, .HRESETn, .HADDR, .HWDATA, .HWRITE, .HSIZE, .HBURST, .HPROT,
|
.HCLK, .HRESETn, .HADDR, .HWDATA, .HWRITE, .HSIZE, .HBURST, .HPROT,
|
||||||
.HTRANS, .HMASTLOCK, .HREADY, .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn,
|
.HTRANS, .HMASTLOCK, .HREADY, .TIMECLK(0), .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn,
|
||||||
.UARTSin, .UARTSout, .SDCCmdIn, .SDCCmdOut, .SDCCmdOE, .SDCDatIn, .SDCCLK);
|
.UARTSin, .UARTSout, .SDCCmdIn, .SDCCmdOut, .SDCCmdOE, .SDCDatIn, .SDCCLK);
|
||||||
|
|
||||||
// Track names of instructions
|
// Track names of instructions
|
||||||
|
|
|
@ -82,7 +82,7 @@ module testbench();
|
||||||
.HRDATAEXT, .HREADYEXT, .HREADY, .HSELEXT, .HRESPEXT, .HCLK,
|
.HRDATAEXT, .HREADYEXT, .HREADY, .HSELEXT, .HRESPEXT, .HCLK,
|
||||||
.HRESETn, .HADDR, .HWDATA, .HWRITE, .HSIZE, .HBURST, .HPROT,
|
.HRESETn, .HADDR, .HWDATA, .HWRITE, .HSIZE, .HBURST, .HPROT,
|
||||||
.HTRANS, .HMASTLOCK,
|
.HTRANS, .HMASTLOCK,
|
||||||
.GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn,
|
.TIMECLK(0), .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn,
|
||||||
.UARTSin, .UARTSout,
|
.UARTSin, .UARTSout,
|
||||||
.SDCCLK, .SDCCmdIn, .SDCCmdOut, .SDCCmdOE, .SDCDatIn);
|
.SDCCLK, .SDCCmdIn, .SDCCmdOut, .SDCCmdOE, .SDCDatIn);
|
||||||
|
|
||||||
|
|
|
@ -152,7 +152,7 @@ logic [3:0] dummy;
|
||||||
|
|
||||||
wallypipelinedsoc dut(.clk, .reset_ext, .reset, .HRDATAEXT,.HREADYEXT, .HRESPEXT,.HSELEXT,
|
wallypipelinedsoc dut(.clk, .reset_ext, .reset, .HRDATAEXT,.HREADYEXT, .HRESPEXT,.HSELEXT,
|
||||||
.HCLK, .HRESETn, .HADDR, .HWDATA, .HWRITE, .HSIZE, .HBURST, .HPROT,
|
.HCLK, .HRESETn, .HADDR, .HWDATA, .HWRITE, .HSIZE, .HBURST, .HPROT,
|
||||||
.HTRANS, .HMASTLOCK, .HREADY, .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn,
|
.HTRANS, .HMASTLOCK, .HREADY, .TIMECLK(1'b0), .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn,
|
||||||
.UARTSin, .UARTSout, .SDCCmdIn, .SDCCmdOut, .SDCCmdOE, .SDCDatIn, .SDCCLK);
|
.UARTSin, .UARTSout, .SDCCmdIn, .SDCCmdOut, .SDCCmdOE, .SDCDatIn, .SDCCLK);
|
||||||
|
|
||||||
// Track names of instructions
|
// Track names of instructions
|
||||||
|
@ -332,9 +332,9 @@ logic [3:0] dummy;
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
module riscvassertions;
|
module riscvassertions;
|
||||||
// Legal number of PMP entries are 0, 16, or 64
|
|
||||||
initial begin
|
initial begin
|
||||||
assert (`PMP_ENTRIES == 0 || `PMP_ENTRIES==16 || `PMP_ENTRIES==64) else $error("Illegal number of PMP entries: PMP_ENTRIES must be 0, 16, or 64");
|
assert (`PMP_ENTRIES == 0 || `PMP_ENTRIES==16 || `PMP_ENTRIES==64) else $error("Illegal number of PMP entries: PMP_ENTRIES must be 0, 16, or 64");
|
||||||
|
assert (`S_SUPPORTED || `MEM_VIRTMEM == 0) else $error("Virtual memory requires S mode support");
|
||||||
assert (`DIV_BITSPERCYCLE == 1 || `DIV_BITSPERCYCLE==2 || `DIV_BITSPERCYCLE==4) else $error("Illegal number of divider bits/cycle: DIV_BITSPERCYCLE must be 1, 2, or 4");
|
assert (`DIV_BITSPERCYCLE == 1 || `DIV_BITSPERCYCLE==2 || `DIV_BITSPERCYCLE==4) else $error("Illegal number of divider bits/cycle: DIV_BITSPERCYCLE must be 1, 2, or 4");
|
||||||
assert (`F_SUPPORTED || ~`D_SUPPORTED) else $error("Can't support double (D) without supporting float (F)");
|
assert (`F_SUPPORTED || ~`D_SUPPORTED) else $error("Can't support double (D) without supporting float (F)");
|
||||||
assert (`XLEN == 64 || ~`D_SUPPORTED) else $error("Wally does not yet support D extensions on RV32");
|
assert (`XLEN == 64 || ~`D_SUPPORTED) else $error("Wally does not yet support D extensions on RV32");
|
||||||
|
@ -351,7 +351,9 @@ module riscvassertions;
|
||||||
assert (2**$clog2(`ITLB_ENTRIES) == `ITLB_ENTRIES || `MEM_VIRTMEM==0) else $error("ITLB_ENTRIES must be a power of 2");
|
assert (2**$clog2(`ITLB_ENTRIES) == `ITLB_ENTRIES || `MEM_VIRTMEM==0) else $error("ITLB_ENTRIES must be a power of 2");
|
||||||
assert (2**$clog2(`DTLB_ENTRIES) == `DTLB_ENTRIES || `MEM_VIRTMEM==0) else $error("DTLB_ENTRIES must be a power of 2");
|
assert (2**$clog2(`DTLB_ENTRIES) == `DTLB_ENTRIES || `MEM_VIRTMEM==0) else $error("DTLB_ENTRIES must be a power of 2");
|
||||||
assert (`RAM_RANGE >= 56'h07FFFFFF) else $warning("Some regression tests will fail if RAM_RANGE is less than 56'h07FFFFFF");
|
assert (`RAM_RANGE >= 56'h07FFFFFF) else $warning("Some regression tests will fail if RAM_RANGE is less than 56'h07FFFFFF");
|
||||||
assert (`ZICSR_SUPPORTED == 1 || (`PMP_ENTRIES == 0 && `MEM_VIRTMEM == 0)) else $error("PMP_ENTRIES and MEM_VIRTMEM must be zero if ZICSR not supported.");
|
assert (`ZICSR_SUPPORTED == 1 || (`PMP_ENTRIES == 0 && `MEM_VIRTMEM == 0)) else $error("PMP_ENTRIES and MEM_VIRTMEM must be zero if ZICSR not supported.");
|
||||||
|
assert (`ZICSR_SUPPORTED == 1 || (`S_SUPPORTED == 0 && `U_SUPPORTED == 0)) else $error("S and U modes not supported if ZISR not supported");
|
||||||
|
assert (`U_SUPPORTED || (`S_SUPPORTED == 0)) else $error ("S mode only supported if U also is supported");
|
||||||
end
|
end
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue