From c0fdd3fbca32230c2f00a3f439aaf14badc674a7 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Wed, 5 Jul 2023 17:30:55 -0500 Subject: [PATCH] Partially solved fpga boot. --- src/uncore/plic_apb.sv | 82 ++++++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 38 deletions(-) diff --git a/src/uncore/plic_apb.sv b/src/uncore/plic_apb.sv index 11c06153d..0014bdd72 100644 --- a/src/uncore/plic_apb.sv +++ b/src/uncore/plic_apb.sv @@ -31,7 +31,6 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`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 @@ -59,19 +58,20 @@ module plic_apb import cvw::*; #(parameter cvw_t P) ( logic [31:0] Din, Dout; // context-independent signals - logic [`N:1] requests; - logic [`N:1][2:0] intPriority; - logic [`N:1] intInProgress, intPending, nextIntPending; + logic [P.PLIC_NUM_SRC:1] requests; + logic [P.PLIC_NUM_SRC:1][2:0] intPriority; + logic [P.PLIC_NUM_SRC:1] intInProgress, intPending, nextIntPending; // context-dependent signals logic [`C-1:0][2:0] intThreshold; - logic [`C-1:0][`N:1] intEn; + logic [`C-1:0][P.PLIC_NUM_SRC:1] intEn; logic [`C-1:0][5:0] intClaim; // ID's are 6 bits if we stay within 63 sources - logic [`C-1:0][7:1][`N:1] irqMatrix; + logic [`C-1:0][7:1][P.PLIC_NUM_SRC:1] irqMatrix; logic [`C-1:0][7:1] priorities_with_irqs; logic [`C-1:0][7:1] max_priority_with_irqs; - logic [`C-1:0][`N:1] irqs_at_max_priority; + logic [`C-1:0][P.PLIC_NUM_SRC:1] irqs_at_max_priority; logic [`C-1:0][7:1] threshMask; + logic [P.PLIC_NUM_SRC-1:0] One; // ======= // AHB I/O @@ -81,6 +81,7 @@ module plic_apb import cvw::*; #(parameter cvw_t P) ( assign memread = ~PWRITE & PSEL; // read at start of access phase. PENABLE hasn't set up before this assign PREADY = 1'b1; // PLIC never takes >1 cycle to respond assign entry = {PADDR[23:2],2'b0}; + assign One[P.PLIC_NUM_SRC-1:1] = '0; assign One[0] = 1'b1; // Vivado does not like this as a single assignment. // account for subword read/write circuitry // -- Note PLIC registers are 32 bits no matter what; access them with LW SW. @@ -92,7 +93,12 @@ module plic_apb import cvw::*; #(parameter cvw_t P) ( assign Din = PWDATA[31:0]; end - if (P.PLIC_NUM_SRC_LT_32) `define PLIC_NUM_SRC_LT_32 + // *** RT: 05 July 2023: BUG BUG BUG. PLIC_NUM_SRC_LT_32 is undefined after parameterization + // the FPGA does work the following code. For now I'm leaving the `define undefined but this + // means the code is only valid for 33 to 64 interrupt sources. In general this needs to be + // rethought for a more generalized implementation. + //if (P.PLIC_NUM_SRC_LT_32) `define PLIC_NUM_SRC_LT_32 + //`define PLIC_NUM_SRC_LT_32 // ================== // Register Interface @@ -101,29 +107,29 @@ module plic_apb import cvw::*; #(parameter cvw_t P) ( always @(posedge PCLK) begin // resetting if (~PRESETn) begin - intPriority <= #1 {`N{3'b0}}; - intEn <= #1 {2*`N{1'b0}}; - intThreshold <= #1 {2{3'b0}}; - intInProgress <= #1 {`N{1'b0}}; + intPriority <= #1 '0; + intEn <= #1 '0; + intThreshold <= #1 '0; + intInProgress <= #1 '0; // writing end else begin if (memwrite) casez(entry) 24'h0000??: intPriority[entry[7:2]] <= #1 Din[2:0]; `ifdef PLIC_NUM_SRC_LT_32 // eventually switch to a generate for loop so as to deprecate PLIC_NUM_SRC_LT_32 and allow up to 1023 sources - 24'h002000: intEn[0][`N:1] <= #1 Din[`N:1]; - 24'h002080: intEn[1][`N:1] <= #1 Din[`N:1]; + 24'h002000: intEn[0][P.PLIC_NUM_SRC:1] <= #1 Din[P.PLIC_NUM_SRC:1]; + 24'h002080: intEn[1][P.PLIC_NUM_SRC:1] <= #1 Din[P.PLIC_NUM_SRC:1]; `endif `ifndef PLIC_NUM_SRC_LT_32 24'h002000: intEn[0][31:1] <= #1 Din[31:1]; - 24'h002004: intEn[0][`N:32] <= #1 Din[31:0]; + 24'h002004: intEn[0][P.PLIC_NUM_SRC:32] <= #1 Din[P.PLIC_NUM_SRC-32:0]; 24'h002080: intEn[1][31:1] <= #1 Din[31:1]; - 24'h002084: intEn[1][`N:32] <= #1 Din[31:0]; + 24'h002084: intEn[1][P.PLIC_NUM_SRC:32] <= #1 Din[P.PLIC_NUM_SRC-32:0]; `endif 24'h200000: intThreshold[0] <= #1 Din[2:0]; - 24'h200004: intInProgress <= #1 intInProgress & ~({{`N-1{1'b0}}, 1'b1} << (Din[5:0]-1)); // lower "InProgress" to signify completion + 24'h200004: intInProgress <= #1 intInProgress & ~(One << (Din[5:0]-1)); // lower "InProgress" to signify completion 24'h201000: intThreshold[1] <= #1 Din[2:0]; - 24'h201004: intInProgress <= #1 intInProgress & ~({{`N-1{1'b0}}, 1'b1} << (Din[5:0]-1)); // lower "InProgress" to signify completion + 24'h201004: intInProgress <= #1 intInProgress & ~(One << (Din[5:0]-1)); // lower "InProgress" to signify completion endcase // Read synchronously because a read can have side effect of changing intInProgress if (memread) begin @@ -131,27 +137,27 @@ module plic_apb import cvw::*; #(parameter cvw_t P) ( 24'h000000: Dout <= #1 32'b0; // there is no intPriority[0] 24'h0000??: Dout <= #1 {29'b0,intPriority[entry[7:2]]}; `ifdef PLIC_NUM_SRC_LT_32 - 24'h001000: Dout <= #1 {{(31-`N){1'b0}},intPending,1'b0}; - 24'h002000: Dout <= #1 {{(31-`N){1'b0}},intEn[0],1'b0}; - 24'h002080: Dout <= #1 {{(31-`N){1'b0}},intEn[1],1'b0}; + 24'h001000: Dout <= #1 {{(31-P.PLIC_NUM_SRC){1'b0}},intPending,1'b0}; + 24'h002000: Dout <= #1 {{(31-P.PLIC_NUM_SRC){1'b0}},intEn[0],1'b0}; + 24'h002080: Dout <= #1 {{(31-P.PLIC_NUM_SRC){1'b0}},intEn[1],1'b0}; `endif `ifndef PLIC_NUM_SRC_LT_32 24'h001000: Dout <= #1 {intPending[31:1],1'b0}; - 24'h001004: Dout <= #1 {{(63-`N){1'b0}},intPending[`N:32]}; + 24'h001004: Dout <= #1 {{(63-P.PLIC_NUM_SRC){1'b0}},intPending[P.PLIC_NUM_SRC:32]}; 24'h002000: Dout <= #1 {intEn[0][31:1],1'b0}; - 24'h002004: Dout <= #1 {{(63-`N){1'b0}},intEn[0][`N:32]}; + 24'h002004: Dout <= #1 {{(63-P.PLIC_NUM_SRC){1'b0}},intEn[0][P.PLIC_NUM_SRC:32]}; 24'h002080: Dout <= #1 {intEn[0][31:1],1'b0}; - 24'h002084: Dout <= #1 {{(63-`N){1'b0}},intEn[1][`N:32]}; + 24'h002084: Dout <= #1 {{(63-P.PLIC_NUM_SRC){1'b0}},intEn[1][P.PLIC_NUM_SRC:32]}; `endif 24'h200000: Dout <= #1 {29'b0,intThreshold[0]}; 24'h200004: begin Dout <= #1 {26'b0,intClaim[0]}; - 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 + intInProgress <= #1 intInProgress | (One << (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-1{1'b0}}, 1'b1} << (intClaim[1]-1)); // claimed requests are currently in progress of being serviced until they are completed + intInProgress <= #1 intInProgress | (One << (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 @@ -161,14 +167,14 @@ module plic_apb import cvw::*; #(parameter cvw_t P) ( // connect sources to requests always_comb begin - requests = {`N{1'b0}}; + requests = {P.PLIC_NUM_SRC{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 request assign nextIntPending = (intPending | requests) & ~intInProgress; - flopr #(`N) intPendingFlop(PCLK,~PRESETn,nextIntPending,intPending); + flopr #(P.PLIC_NUM_SRC) intPendingFlop(PCLK,~PRESETn,nextIntPending,intPending); // context-dependent signals genvar ctx; @@ -181,7 +187,7 @@ module plic_apb import cvw::*; #(parameter cvw_t P) ( // ("active" meaning it is enabled in context and is pending) genvar src, pri; for (pri=1; pri<=7; pri++) begin - for (src=1; src<=`N; src++) begin + for (src=1; src<=P.PLIC_NUM_SRC; src++) begin assign irqMatrix[ctx][pri][src] = (intPriority[src]==pri) & intPending[src] & intEn[ctx][src]; end end @@ -210,14 +216,14 @@ module plic_apb import cvw::*; #(parameter cvw_t P) ( // of the sources at the highest priority level that has active requests, // which sources have active requests? - assign irqs_at_max_priority[ctx][`N:1] = - ({`N{max_priority_with_irqs[ctx][7]}} & irqMatrix[ctx][7]) | - ({`N{max_priority_with_irqs[ctx][6]}} & irqMatrix[ctx][6]) | - ({`N{max_priority_with_irqs[ctx][5]}} & irqMatrix[ctx][5]) | - ({`N{max_priority_with_irqs[ctx][4]}} & irqMatrix[ctx][4]) | - ({`N{max_priority_with_irqs[ctx][3]}} & irqMatrix[ctx][3]) | - ({`N{max_priority_with_irqs[ctx][2]}} & irqMatrix[ctx][2]) | - ({`N{max_priority_with_irqs[ctx][1]}} & irqMatrix[ctx][1]); + assign irqs_at_max_priority[ctx][P.PLIC_NUM_SRC:1] = + ({P.PLIC_NUM_SRC{max_priority_with_irqs[ctx][7]}} & irqMatrix[ctx][7]) | + ({P.PLIC_NUM_SRC{max_priority_with_irqs[ctx][6]}} & irqMatrix[ctx][6]) | + ({P.PLIC_NUM_SRC{max_priority_with_irqs[ctx][5]}} & irqMatrix[ctx][5]) | + ({P.PLIC_NUM_SRC{max_priority_with_irqs[ctx][4]}} & irqMatrix[ctx][4]) | + ({P.PLIC_NUM_SRC{max_priority_with_irqs[ctx][3]}} & irqMatrix[ctx][3]) | + ({P.PLIC_NUM_SRC{max_priority_with_irqs[ctx][2]}} & irqMatrix[ctx][2]) | + ({P.PLIC_NUM_SRC{max_priority_with_irqs[ctx][1]}} & irqMatrix[ctx][1]); // of the sources at the highest priority level that has active requests, // choose the source with the lowest source ID to be the most urgent @@ -225,7 +231,7 @@ module plic_apb import cvw::*; #(parameter cvw_t P) ( integer k; always_comb begin intClaim[ctx] = 6'b0; - for (k=`N; k>0; k--) begin + for (k=P.PLIC_NUM_SRC; k>0; k--) begin if (irqs_at_max_priority[ctx][k]) intClaim[ctx] = k[5:0]; end end