mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
greatly improved PLIC register interface
This commit is contained in:
parent
939e36a151
commit
c796547156
@ -95,6 +95,8 @@
|
||||
|
||||
// Interrupt configuration
|
||||
`define PLIC_NUM_SRC 4
|
||||
// comment out the following if >=32 sources
|
||||
`define PLIC_NUM_SRC_LT_32
|
||||
`define PLIC_GPIO_ID 3
|
||||
`define PLIC_UART_ID 4
|
||||
|
||||
|
@ -96,6 +96,8 @@
|
||||
|
||||
// Interrupt configuration
|
||||
`define PLIC_NUM_SRC 4
|
||||
// comment out the following if >=32 sources
|
||||
`define PLIC_NUM_SRC_LT_32
|
||||
`define PLIC_GPIO_ID 3
|
||||
`define PLIC_UART_ID 4
|
||||
|
||||
|
@ -12,8 +12,6 @@
|
||||
// *** Big questions:
|
||||
// Do we detect requests as level-triggered or edge-trigged?
|
||||
// If edge-triggered, do we want to allow 1 source to be able to make a number of repeated requests?
|
||||
// Should PLIC also output SEIP or just MEIP?
|
||||
// MEIP is the same as ExtIntM, right?
|
||||
//
|
||||
// A component of the Wally configurable RISC-V project.
|
||||
//
|
||||
@ -65,7 +63,9 @@ module plic (
|
||||
logic [N:1] pendingRequestsAtMaxP;
|
||||
logic [7:1] threshMask;
|
||||
|
||||
// =======
|
||||
// AHB I/O
|
||||
// =======
|
||||
assign entry = {HADDR[27:2],2'b0};
|
||||
assign initTrans = HREADY & HSELPLIC & (HTRANS != 2'b00);
|
||||
assign memread = initTrans & ~HWRITE;
|
||||
@ -77,7 +77,8 @@ module plic (
|
||||
|
||||
// account for subword read/write circuitry
|
||||
// -- Note PLIC registers are 32 bits no matter what; access them with LW SW.
|
||||
generate // *** add ld, sd functionality
|
||||
// *** add ld, sd functionality
|
||||
generate
|
||||
if (`XLEN == 64) begin
|
||||
always_comb
|
||||
if (entryd[2]) begin
|
||||
@ -95,71 +96,54 @@ module plic (
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// register interface
|
||||
genvar i;
|
||||
generate
|
||||
// priority registers
|
||||
for (i=1; i<=N; i=i+1)
|
||||
always @(posedge HCLK,negedge HRESETn)
|
||||
if (~HRESETn)
|
||||
intPriority[i] <= 3'b0;
|
||||
else begin
|
||||
if (entry == 28'hc000000+4*i) // *** make sure this does not synthesize into N 28-bit equality comparators; we want something more decoder-ish
|
||||
Dout <= #1 {{(`XLEN-3){1'b0}},intPriority[i]};
|
||||
if ((entryd == 28'hc000000+4*i) && memwrite)
|
||||
intPriority[i] <= #1 Din[2:0];
|
||||
end
|
||||
|
||||
// pending and enable registers
|
||||
if (N<32)
|
||||
always @(posedge HCLK,negedge HRESETn)
|
||||
if (~HRESETn)
|
||||
intEn <= {N{1'b0}};
|
||||
else begin
|
||||
if (entry == 28'hc001000)
|
||||
Dout <= #1 {{(31-N){1'b0}},intPending[N:1],1'b0};
|
||||
if (entry == 28'hc002000)
|
||||
Dout <= #1 {{(31-N){1'b0}},intEn[N:1],1'b0};
|
||||
if ((entryd == 28'hc002000) && memwrite)
|
||||
intEn[N:1] <= #1 Din[N:1];
|
||||
end
|
||||
else // N>=32
|
||||
always @(posedge HCLK,negedge HRESETn)
|
||||
if (~HRESETn)
|
||||
intEn <= {N{1'b0}};
|
||||
else begin
|
||||
if (entry == 28'hc001000)
|
||||
Dout <= #1 {intPending[31:1],1'b0};
|
||||
if (entry == 28'hc001004)
|
||||
Dout <= #1 {{(63-N){1'b0}},intPending[N:32]};
|
||||
if (entry == 28'hc002000)
|
||||
Dout <= #1 {intEn[31:1],1'b0};
|
||||
if (entry == 28'hc002004)
|
||||
Dout <= #1 {{(63-N){1'b0}},intEn[N:32]};
|
||||
if ((entryd == 28'hc002000) && memwrite)
|
||||
intEn[31:1] <= #1 Din[31:1];
|
||||
if ((entryd == 28'hc002004) && memwrite)
|
||||
intEn[N:32] <= #1 Din[31:0];
|
||||
end
|
||||
|
||||
// threshold and claim/complete registers
|
||||
always @(posedge HCLK, negedge HRESETn)
|
||||
if (~HRESETn) begin
|
||||
intThreshold<=3'b0;
|
||||
intInProgress <= {N{1'b0}};
|
||||
end else begin
|
||||
if (entry == 28'hc200000)
|
||||
Dout <= #1 {29'b0,intThreshold[2:0]};
|
||||
if ((entryd == 28'hc200000) && memwrite)
|
||||
intThreshold[2:0] <= #1 Din[2:0];
|
||||
if ((entry == 28'hc200004) && memread) begin // check for memread because reading claim reg. has side effects
|
||||
// ==================
|
||||
// Register Interface
|
||||
// ==================
|
||||
always @(posedge HCLK,negedge HRESETn) begin
|
||||
// resetting
|
||||
if (~HRESETn) begin
|
||||
intPriority <= #1 '{default:3'b0}; // *** does this initialization synthesize cleanly?
|
||||
intEn <= #1 {N{1'b0}};
|
||||
intThreshold <= #1 3'b0;
|
||||
intInProgress <= #1 {N{1'b0}};
|
||||
// writing
|
||||
end else if (memwrite)
|
||||
casez(entryd)
|
||||
28'hc0000??: intPriority[entryd[7:2]] <= #1 Din[2:0];
|
||||
`ifdef PLIC_NUM_SRC_LT_32
|
||||
28'hc002000: intEn[N:1] <= #1 Din[N:1];
|
||||
`endif
|
||||
`ifndef PLIC_NUM_SRC_LT_32
|
||||
28'hc002000: intEn[31:1] <= #1 Din[31:1];
|
||||
28'hc002004: intEn[N:32] <= #1 Din[31:0];
|
||||
`endif
|
||||
28'hc200000: intThreshold[2:0] <= #1 Din[2:0];
|
||||
28'hc200004: intInProgress <= #1 intInProgress & ~(1'b1 << (Din[5:0]-1)); // lower "InProgress" to signify completion
|
||||
endcase
|
||||
// reading
|
||||
if (memread)
|
||||
casez(entry)
|
||||
28'hc0000??: Dout <= #1 {{(`XLEN-3){1'b0}},intPriority[entry[7:2]]};
|
||||
`ifdef PLIC_NUM_SRC_LT_32
|
||||
28'hc001000: Dout <= #1 {{(31-N){1'b0}},intPending[N:1],1'b0};
|
||||
28'hc002000: Dout <= #1 {{(31-N){1'b0}},intEn[N:1],1'b0};
|
||||
`endif
|
||||
`ifndef PLIC_NUM_SRC_LT_32
|
||||
28'hc001000: Dout <= #1 {intPending[31:1],1'b0};
|
||||
28'hc001004: Dout <= #1 {{(63-N){1'b0}},intPending[N:32]};
|
||||
28'hc002000: Dout <= #1 {intEn[31:1],1'b0};
|
||||
28'hc002004: Dout <= #1 {{(63-N){1'b0}},intEn[N:32]};
|
||||
`endif
|
||||
28'hc200000: Dout <= #1 {29'b0,intThreshold[2:0]};
|
||||
28'hc200004: begin
|
||||
Dout <= #1 {26'b0,intClaim};
|
||||
intInProgress <= #1 intInProgress | (1'b1 << (intClaim-1)); // claimed requests are currently in progress of being serviced until they are completed
|
||||
end
|
||||
if ((entryd == 28'hc200004) && memwrite)
|
||||
intInProgress <= #1 intInProgress & ~(1'b1 << (Din[5:0]-1)); // lower "InProgress" to signify completion
|
||||
end
|
||||
endgenerate
|
||||
default: Dout <= #1 32'hdeadbeef; // invalid access
|
||||
endcase
|
||||
else
|
||||
Dout <= #1 32'h0;
|
||||
end
|
||||
|
||||
// connect sources to requests
|
||||
always_comb begin
|
||||
@ -179,6 +163,7 @@ module plic (
|
||||
flopr #(N) intPendingFlop(HCLK,~HRESETn,nextIntPending,intPending);
|
||||
|
||||
// pending array - indexed by priority_lvl x source_ID
|
||||
genvar i;
|
||||
generate
|
||||
for (i=1; i<=N; i=i+1) begin
|
||||
// *** make sure that this synthesizes into N decoders, not 7*N 3-bit equality comparators (right?)
|
||||
|
Loading…
Reference in New Issue
Block a user