mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
rv32 plic test and lint fixes
This commit is contained in:
parent
61beedf275
commit
182bfdbb0e
@ -85,7 +85,7 @@
|
|||||||
// Test modes
|
// Test modes
|
||||||
|
|
||||||
// Tie GPIO outputs back to inputs
|
// Tie GPIO outputs back to inputs
|
||||||
`define GPIO_LOOPBACK_TEST 0
|
`define GPIO_LOOPBACK_TEST 1
|
||||||
|
|
||||||
// Busybear special CSR config to match OVPSim
|
// Busybear special CSR config to match OVPSim
|
||||||
`define OVPSIM_CSR_CONFIG 0
|
`define OVPSIM_CSR_CONFIG 0
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
`include "wally-config.vh"
|
`include "wally-config.vh"
|
||||||
|
|
||||||
package ahbliteState;
|
package ahbliteState;
|
||||||
typedef enum {IDLE, MEMREAD, MEMWRITE, INSTRREAD, INSTRREADC, ATOMICREAD, ATOMICWRITE, MMUTRANSLATE} statetype;
|
typedef enum {IDLE, MEMREAD, MEMWRITE, INSTRREAD, ATOMICREAD, ATOMICWRITE, MMUTRANSLATE} statetype;
|
||||||
endpackage
|
endpackage
|
||||||
|
|
||||||
module ahblite (
|
module ahblite (
|
||||||
@ -127,7 +127,7 @@ module ahblite (
|
|||||||
else if (InstrReadF) NextBusState = INSTRREAD;
|
else if (InstrReadF) NextBusState = INSTRREAD;
|
||||||
else NextBusState = IDLE;
|
else NextBusState = IDLE;
|
||||||
MEMREAD: if (~HREADY) NextBusState = MEMREAD;
|
MEMREAD: if (~HREADY) NextBusState = MEMREAD;
|
||||||
else if (InstrReadF) NextBusState = INSTRREADC;
|
else if (InstrReadF) NextBusState = INSTRREAD;
|
||||||
else NextBusState = IDLE;
|
else NextBusState = IDLE;
|
||||||
MEMWRITE: if (~HREADY) NextBusState = MEMWRITE;
|
MEMWRITE: if (~HREADY) NextBusState = MEMWRITE;
|
||||||
else if (InstrReadF) NextBusState = INSTRREAD;
|
else if (InstrReadF) NextBusState = INSTRREAD;
|
||||||
@ -135,8 +135,6 @@ module ahblite (
|
|||||||
INSTRREAD:
|
INSTRREAD:
|
||||||
if (~HREADY) NextBusState = INSTRREAD;
|
if (~HREADY) NextBusState = INSTRREAD;
|
||||||
else NextBusState = IDLE; // if (InstrReadF still high)
|
else NextBusState = IDLE; // if (InstrReadF still high)
|
||||||
INSTRREADC: if (~HREADY) NextBusState = INSTRREADC; // "C" for "competing", meaning please don't mess up the memread in the W stage.
|
|
||||||
else NextBusState = IDLE;
|
|
||||||
default: NextBusState = IDLE;
|
default: NextBusState = IDLE;
|
||||||
endcase
|
endcase
|
||||||
|
|
||||||
@ -147,12 +145,12 @@ module ahblite (
|
|||||||
(NextBusState == ATOMICREAD) || (NextBusState == ATOMICWRITE) ||
|
(NextBusState == ATOMICREAD) || (NextBusState == ATOMICWRITE) ||
|
||||||
MMUStall);
|
MMUStall);
|
||||||
|
|
||||||
assign #1 InstrStall = ((NextBusState == INSTRREAD) || (NextBusState == INSTRREADC) ||
|
//assign #1 InstrStall = ((NextBusState == INSTRREAD) || (NextBusState == INSTRREADC) ||
|
||||||
MMUStall);
|
// MMUStall);
|
||||||
|
|
||||||
// Determine access type (important for determining whether to fault)
|
// Determine access type (important for determining whether to fault)
|
||||||
assign Atomic = ((NextBusState == ATOMICREAD) || (NextBusState == ATOMICWRITE));
|
assign Atomic = ((NextBusState == ATOMICREAD) || (NextBusState == ATOMICWRITE));
|
||||||
assign Execute = ((NextBusState == INSTRREAD) || (NextBusState == INSTRREADC));
|
assign Execute = ((NextBusState == INSTRREAD));
|
||||||
assign Write = ((NextBusState == MEMWRITE) || (NextBusState == ATOMICWRITE));
|
assign Write = ((NextBusState == MEMWRITE) || (NextBusState == ATOMICWRITE));
|
||||||
assign Read = ((NextBusState == MEMREAD) || (NextBusState == ATOMICREAD) ||
|
assign Read = ((NextBusState == MEMREAD) || (NextBusState == ATOMICREAD) ||
|
||||||
(NextBusState == MMUTRANSLATE));
|
(NextBusState == MMUTRANSLATE));
|
||||||
@ -187,7 +185,7 @@ module ahblite (
|
|||||||
assign MMUReady = (BusState == MMUTRANSLATE && NextBusState == IDLE);
|
assign MMUReady = (BusState == MMUTRANSLATE && NextBusState == IDLE);
|
||||||
|
|
||||||
assign InstrRData = HRDATA;
|
assign InstrRData = HRDATA;
|
||||||
assign InstrAckF = (BusState == INSTRREAD) && (NextBusState != INSTRREAD) || (BusState == INSTRREADC) && (NextBusState != INSTRREADC);
|
assign InstrAckF = (BusState == INSTRREAD) && (NextBusState != INSTRREAD);
|
||||||
assign MemAckW = (BusState == MEMREAD) && (NextBusState != MEMREAD) || (BusState == MEMWRITE) && (NextBusState != MEMWRITE) ||
|
assign MemAckW = (BusState == MEMREAD) && (NextBusState != MEMREAD) || (BusState == MEMWRITE) && (NextBusState != MEMWRITE) ||
|
||||||
((BusState == ATOMICREAD) && (NextBusState != ATOMICREAD)) || ((BusState == ATOMICWRITE) && (NextBusState != ATOMICWRITE));
|
((BusState == ATOMICREAD) && (NextBusState != ATOMICREAD)) || ((BusState == ATOMICWRITE) && (NextBusState != ATOMICWRITE));
|
||||||
assign MMUReadPTE = HRDATA;
|
assign MMUReadPTE = HRDATA;
|
||||||
|
@ -82,6 +82,37 @@ module gpio (
|
|||||||
|
|
||||||
// register access
|
// register access
|
||||||
always_ff @(posedge HCLK, negedge HRESETn) begin
|
always_ff @(posedge HCLK, negedge HRESETn) begin
|
||||||
|
// writes
|
||||||
|
if (~HRESETn) begin
|
||||||
|
// asynch reset
|
||||||
|
input_en <= 0;
|
||||||
|
output_en <= 0;
|
||||||
|
// *** synch reset not yet implemented
|
||||||
|
output_val <= #1 0;
|
||||||
|
rise_ie <= #1 0;
|
||||||
|
rise_ip <= #1 0;
|
||||||
|
fall_ie <= #1 0;
|
||||||
|
fall_ip <= #1 0;
|
||||||
|
high_ie <= #1 0;
|
||||||
|
high_ip <= #1 0;
|
||||||
|
low_ie <= #1 0;
|
||||||
|
low_ip <= #1 0;
|
||||||
|
end else begin
|
||||||
|
// writes
|
||||||
|
if (memwrite)
|
||||||
|
// According to FE310 spec: Once the interrupt is pending, it will remain set until a 1 is written to the *_ip register at that bit.
|
||||||
|
/* verilator lint_off CASEINCOMPLETE */
|
||||||
|
case(entryd)
|
||||||
|
8'h04: input_en <= #1 Din;
|
||||||
|
8'h08: output_en <= #1 Din;
|
||||||
|
8'h0C: output_val <= #1 Din;
|
||||||
|
8'h18: rise_ie <= #1 Din;
|
||||||
|
8'h20: fall_ie <= #1 Din;
|
||||||
|
8'h28: high_ie <= #1 Din;
|
||||||
|
8'h30: low_ie <= #1 Din;
|
||||||
|
8'h40: output_val <= #1 output_val ^ Din; // OUT_XOR
|
||||||
|
endcase
|
||||||
|
/* verilator lint_on CASEINCOMPLETE */
|
||||||
// reads
|
// reads
|
||||||
case(entry)
|
case(entry)
|
||||||
8'h00: Dout <= #1 input_val;
|
8'h00: Dout <= #1 input_val;
|
||||||
@ -99,56 +130,7 @@ module gpio (
|
|||||||
8'h40: Dout <= #1 0; // OUT_XOR reads as 0
|
8'h40: Dout <= #1 0; // OUT_XOR reads as 0
|
||||||
default: Dout <= #1 0;
|
default: Dout <= #1 0;
|
||||||
endcase
|
endcase
|
||||||
// writes
|
|
||||||
if (~HRESETn) begin
|
|
||||||
// asynch reset
|
|
||||||
input_en <= 0;
|
|
||||||
output_en <= 0;
|
|
||||||
// *** synch reset not yet implemented
|
|
||||||
output_val <= #1 0;
|
|
||||||
rise_ie <= #1 0;
|
|
||||||
rise_ip <= #1 0;
|
|
||||||
fall_ie <= #1 0;
|
|
||||||
fall_ip <= #1 0;
|
|
||||||
high_ie <= #1 0;
|
|
||||||
high_ip <= #1 0;
|
|
||||||
low_ie <= #1 0;
|
|
||||||
low_ip <= #1 0;
|
|
||||||
end else if (memwrite)
|
|
||||||
// According to FE310 spec: Once the interrupt is pending, it will remain set until a 1 is written to the *_ip register at that bit.
|
|
||||||
case(entryd)
|
|
||||||
8'h04: input_en <= #1 Din;
|
|
||||||
8'h08: output_en <= #1 Din;
|
|
||||||
8'h0C: output_val <= #1 Din;
|
|
||||||
8'h18: rise_ie <= #1 Din;
|
|
||||||
8'h1C: rise_ip <= #1 rise_ip & ~Din;
|
|
||||||
8'h20: fall_ie <= #1 Din;
|
|
||||||
8'h24: fall_ip <= #1 fall_ip & ~Din;
|
|
||||||
8'h28: high_ie <= #1 Din;
|
|
||||||
8'h2C: high_ip <= #1 high_ip & ~Din;
|
|
||||||
8'h30: low_ie <= #1 Din;
|
|
||||||
8'h34: low_ip <= #1 low_ip & ~Din;
|
|
||||||
8'h40: output_val <= #1 output_val ^ Din; // OUT_XOR
|
|
||||||
endcase
|
|
||||||
end
|
|
||||||
|
|
||||||
// chip i/o
|
|
||||||
generate
|
|
||||||
if (`GPIO_LOOPBACK_TEST) // connect OUT to IN for loopback testing
|
|
||||||
assign input0d = GPIOPinsOut & input_en & output_en;
|
|
||||||
else
|
|
||||||
assign input0d = GPIOPinsIn & input_en;
|
|
||||||
endgenerate
|
|
||||||
// *** this costs lots of flops; I suspect they don't need to be resettable, do they?
|
|
||||||
flop #(32) sync1(HCLK,input0d,input1d);
|
|
||||||
flop #(32) sync2(HCLK,input1d,input2d);
|
|
||||||
flop #(32) sync3(HCLK,input2d,input3d);
|
|
||||||
assign input_val = input3d;
|
|
||||||
assign GPIOPinsOut = output_val;
|
|
||||||
assign GPIOPinsEn = output_en;
|
|
||||||
|
|
||||||
// interrupts
|
// interrupts
|
||||||
always_ff @(posedge HCLK) begin
|
|
||||||
if (memwrite && (entryd == 8'h1C))
|
if (memwrite && (entryd == 8'h1C))
|
||||||
rise_ip <= rise_ip & ~Din | (input2d & ~input3d);
|
rise_ip <= rise_ip & ~Din | (input2d & ~input3d);
|
||||||
else
|
else
|
||||||
@ -166,6 +148,23 @@ module gpio (
|
|||||||
else
|
else
|
||||||
low_ip <= low_ip | ~input3d;
|
low_ip <= low_ip | ~input3d;
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// chip i/o
|
||||||
|
generate
|
||||||
|
if (`GPIO_LOOPBACK_TEST) // connect OUT to IN for loopback testing
|
||||||
|
assign input0d = GPIOPinsOut & input_en & output_en;
|
||||||
|
else
|
||||||
|
assign input0d = GPIOPinsIn & input_en;
|
||||||
|
endgenerate
|
||||||
|
// *** this costs lots of flops; I suspect they don't need to be resettable, do they?
|
||||||
|
flop #(32) sync1(HCLK,input0d,input1d);
|
||||||
|
flop #(32) sync2(HCLK,input1d,input2d);
|
||||||
|
flop #(32) sync3(HCLK,input2d,input3d);
|
||||||
|
assign input_val = input3d;
|
||||||
|
assign GPIOPinsOut = output_val;
|
||||||
|
assign GPIOPinsEn = output_en;
|
||||||
|
|
||||||
assign GPIOIntr = |{(rise_ip & rise_ie),(fall_ip & fall_ip),(high_ip & high_ie),(low_ip & low_ie)};
|
assign GPIOIntr = |{(rise_ip & rise_ie),(fall_ip & fall_ip),(high_ip & high_ie),(low_ip & low_ie)};
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
@ -106,7 +106,8 @@ module plic (
|
|||||||
intThreshold <= #1 3'b0;
|
intThreshold <= #1 3'b0;
|
||||||
intInProgress <= #1 {N{1'b0}};
|
intInProgress <= #1 {N{1'b0}};
|
||||||
// writing
|
// writing
|
||||||
end else if (memwrite)
|
end else begin
|
||||||
|
if (memwrite)
|
||||||
casez(entryd)
|
casez(entryd)
|
||||||
28'hc0000??: intPriority[entryd[7:2]] <= #1 Din[2:0];
|
28'hc0000??: intPriority[entryd[7:2]] <= #1 Din[2:0];
|
||||||
`ifdef PLIC_NUM_SRC_LT_32
|
`ifdef PLIC_NUM_SRC_LT_32
|
||||||
@ -143,6 +144,7 @@ module plic (
|
|||||||
else
|
else
|
||||||
Dout <= #1 32'h0;
|
Dout <= #1 32'h0;
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
// connect sources to requests
|
// connect sources to requests
|
||||||
always_comb begin
|
always_comb begin
|
||||||
|
@ -425,7 +425,7 @@ module testbench();
|
|||||||
if (TESTSPERIPH) begin
|
if (TESTSPERIPH) begin
|
||||||
tests = tests32periph;
|
tests = tests32periph;
|
||||||
end else begin
|
end else begin
|
||||||
tests = {tests32i, tests32p};//,tests32periph}; *** broken at the moment
|
tests = {tests32i, tests32p, tests32periph};
|
||||||
if (`C_SUPPORTED % 2 == 1) tests = {tests, tests32ic};
|
if (`C_SUPPORTED % 2 == 1) tests = {tests, tests32ic};
|
||||||
else tests = {tests, tests32iNOc};
|
else tests = {tests, tests32iNOc};
|
||||||
if (`M_SUPPORTED % 2 == 1) tests = {tests, tests32m};
|
if (`M_SUPPORTED % 2 == 1) tests = {tests, tests32m};
|
||||||
|
Loading…
Reference in New Issue
Block a user