diff --git a/src/uncore/clint_apb.sv b/src/uncore/clint_apb.sv index 997c1bd39..c416f2938 100644 --- a/src/uncore/clint_apb.sv +++ b/src/uncore/clint_apb.sv @@ -42,6 +42,11 @@ module clint_apb import cvw::*; #(parameter cvw_t P) ( output logic MTimerInt, MSwInt ); + // register map + localparam CLINT_MSIP = 16'h0000; + localparam CLINT_MTIMECMP = 16'h4000; + localparam CLINT_MTIME = 16'hBFF8; + logic MSIP; logic [15:0] entry; logic memwrite; @@ -65,19 +70,19 @@ module clint_apb import cvw::*; #(parameter cvw_t P) ( if (P.XLEN==64) begin:clint // 64-bit always_ff @(posedge PCLK) begin case(entry) - 16'h0000: PRDATA <= {63'b0, MSIP}; - 16'h4000: PRDATA <= MTIMECMP; - 16'hBFF8: PRDATA <= MTIME; - default: PRDATA <= 0; + CLINT_MSIP: PRDATA <= {63'b0, MSIP}; + CLINT_MTIMECMP: PRDATA <= MTIMECMP; + CLINT_MTIME: PRDATA <= MTIME; + default: PRDATA <= '0; endcase end always_ff @(posedge PCLK or negedge PRESETn) if (~PRESETn) begin - MSIP <= 0; + MSIP <= 1'b0; MTIMECMP <= 64'hFFFFFFFFFFFFFFFF; // Spec says MTIMECMP is not reset, but we reset to maximum value to prevent spurious timer interrupts end else if (memwrite) begin - if (entry == 16'h0000) MSIP <= PWDATA[0]; - if (entry == 16'h4000) begin + if (entry == CLINT_MSIP) MSIP <= PWDATA[0]; + if (entry == CLINT_MTIMECMP) begin for(i=0;i1 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. + 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. @@ -107,48 +120,49 @@ module plic_apb import cvw::*; #(parameter cvw_t P) ( always_ff @(posedge PCLK) begin // resetting if (~PRESETn) begin - intPriority <= 0; - intEn <= 0; - intThreshold <= 0; - intInProgress <= 0; + intPriority <= '0; + intEn <= '0; + intThreshold <= '0; + intInProgress <= '0; // writing end else begin if (memwrite) casez(entry) - 24'h0000??: intPriority[entry[7:2]] <= Din[2:0]; - 24'h002000: intEn[0][PLIC_NUM_SRC_MIN_32:1] <= Din[PLIC_NUM_SRC_MIN_32:1]; - 24'h002080: intEn[1][PLIC_NUM_SRC_MIN_32:1] <= Din[PLIC_NUM_SRC_MIN_32:1]; - 24'h002004: if (P.PLIC_NUM_SRC >= 32) intEn[0][PLIC_SRC_TOP:PLIC_SRC_BOT] <= Din[PLIC_SRC_DINTOP:0]; - 24'h002084: if (P.PLIC_NUM_SRC >= 32) intEn[1][PLIC_SRC_TOP:PLIC_SRC_BOT] <= Din[PLIC_SRC_DINTOP:0]; - 24'h200000: intThreshold[0] <= Din[2:0]; - 24'h200004: intInProgress <= intInProgress & ~(One << (Din[5:0]-1)); // lower "InProgress" to signify completion - 24'h201000: intThreshold[1] <= Din[2:0]; - 24'h201004: intInProgress <= intInProgress & ~(One << (Din[5:0]-1)); // lower "InProgress" to signify completion + 24'h0000??: intPriority[entry[7:2]] <= Din[2:0]; + PLIC_INTEN00: intEn[0][PLIC_NUM_SRC_MIN_32:1] <= Din[PLIC_NUM_SRC_MIN_32:1]; + PLIC_INTEN10: intEn[1][PLIC_NUM_SRC_MIN_32:1] <= Din[PLIC_NUM_SRC_MIN_32:1]; + PLIC_INTEN01: if (P.PLIC_NUM_SRC >= 32) intEn[0][PLIC_SRC_TOP:PLIC_SRC_BOT] <= Din[PLIC_SRC_DINTOP:0]; + PLIC_INTEN11: if (P.PLIC_NUM_SRC >= 32) intEn[1][PLIC_SRC_TOP:PLIC_SRC_BOT] <= Din[PLIC_SRC_DINTOP:0]; + PLIC_THRESHOLD0: intThreshold[0] <= Din[2:0]; + PLIC_CLAIMCOMPLETE0: intInProgress <= intInProgress & ~(One << (Din[5:0]-1)); // lower "InProgress" to signify completion + PLIC_THRESHOLD1: intThreshold[1] <= Din[2:0]; + PLIC_CLAIMCOMPLETE1: intInProgress <= 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 casez(entry) - 24'h000000: Dout <= 32'b0; // there is no intPriority[0] - 24'h0000??: Dout <= {29'b0,intPriority[entry[7:2]]}; - 24'h001000: Dout <= {{(31-PLIC_NUM_SRC_MIN_32){1'b0}},intPending[PLIC_NUM_SRC_MIN_32:1],1'b0}; - 24'h002000: Dout <= {{(31-PLIC_NUM_SRC_MIN_32){1'b0}},intEn[0][PLIC_NUM_SRC_MIN_32:1],1'b0}; - 24'h001004: if (P.PLIC_NUM_SRC >= 32) Dout <= {{(PLIC_SRC_EXT){1'b0}},intPending[PLIC_SRC_TOP:PLIC_SRC_BOT]}; - 24'h002004: if (P.PLIC_NUM_SRC >= 32) Dout <= {{(PLIC_SRC_EXT){1'b0}},intEn[0][PLIC_SRC_TOP:PLIC_SRC_BOT]}; - 24'h002080: Dout <= {{(31-PLIC_NUM_SRC_MIN_32){1'b0}},intEn[1][PLIC_NUM_SRC_MIN_32:1],1'b0}; - 24'h002084: if (P.PLIC_NUM_SRC >= 32) Dout <= {{(PLIC_SRC_EXT){1'b0}},intEn[1][PLIC_SRC_TOP:PLIC_SRC_BOT]}; - 24'h200000: Dout <= {29'b0,intThreshold[0]}; - 24'h200004: begin + PLIC_INTPRIORITY0: Dout <= 32'b0; // there is no intPriority[0] + 24'h0000??: Dout <= {29'b0,intPriority[entry[7:2]]}; + PLIC_INTPENDING0: Dout <= {{(31-PLIC_NUM_SRC_MIN_32){1'b0}},intPending[PLIC_NUM_SRC_MIN_32:1],1'b0}; + PLIC_INTEN00: Dout <= {{(31-PLIC_NUM_SRC_MIN_32){1'b0}},intEn[0][PLIC_NUM_SRC_MIN_32:1],1'b0}; + PLIC_INTPENDING1: if (P.PLIC_NUM_SRC >= 32) Dout <= {{(PLIC_SRC_EXT){1'b0}},intPending[PLIC_SRC_TOP:PLIC_SRC_BOT]}; + PLIC_INTEN01: if (P.PLIC_NUM_SRC >= 32) Dout <= {{(PLIC_SRC_EXT){1'b0}},intEn[0][PLIC_SRC_TOP:PLIC_SRC_BOT]}; + PLIC_INTEN10: Dout <= {{(31-PLIC_NUM_SRC_MIN_32){1'b0}},intEn[1][PLIC_NUM_SRC_MIN_32:1],1'b0}; + PLIC_INTEN11: if (P.PLIC_NUM_SRC >= 32) Dout <= {{(PLIC_SRC_EXT){1'b0}},intEn[1][PLIC_SRC_TOP:PLIC_SRC_BOT]}; + PLIC_THRESHOLD0: Dout <= {29'b0,intThreshold[0]}; + PLIC_CLAIMCOMPLETE0: begin Dout <= {26'b0,intClaim[0]}; intInProgress <= intInProgress | (One << (intClaim[0]-1)); // claimed requests are currently in progress of being serviced until they are completed end - 24'h201000: Dout <= {29'b0,intThreshold[1]}; - 24'h201004: begin + PLIC_THRESHOLD1: Dout <= {29'b0,intThreshold[1]}; + PLIC_CLAIMCOMPLETE1: begin Dout <= {26'b0,intClaim[1]}; intInProgress <= intInProgress | (One << (intClaim[1]-1)); // claimed requests are currently in progress of being serviced until they are completed end - default: Dout <= 32'h0; // invalid access + default: Dout <= 32'h0; // invalid access endcase - end else Dout <= 32'h0; + end else Dout <= 32'h0; end end diff --git a/src/uncore/ram_ahb.sv b/src/uncore/ram_ahb.sv index d26161f4f..ed4b4d9ec 100644 --- a/src/uncore/ram_ahb.sv +++ b/src/uncore/ram_ahb.sv @@ -64,7 +64,7 @@ module ram_ahb import cvw::*; #(parameter cvw_t P, assign nextHREADYRam = (~(memwriteD & memread)) & ~DelayReady; flopr #(1) readyreg(HCLK, ~HRESETn, nextHREADYRam, HREADYRam); - assign HRESPRam = 0; // OK + assign HRESPRam = 1'b0; // OK // On writes or during a wait state, use address delayed by one cycle to sync RamAddr with HWDATA or hold stalled address mux2 #(P.PA_BITS) adrmux(HADDR, HADDRD, memwriteD | ~HREADY, RamAddr); @@ -104,7 +104,7 @@ module ram_ahb import cvw::*; #(parameter cvw_t P, assign DelayReady = NextState == DELAY; assign CntRst = NextState == READY; end else begin - assign DelayReady = 0; + assign DelayReady = 1'b0; end endmodule diff --git a/src/uncore/spi_apb.sv b/src/uncore/spi_apb.sv index 3f34e938e..b54480de3 100644 --- a/src/uncore/spi_apb.sv +++ b/src/uncore/spi_apb.sv @@ -45,6 +45,22 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( output logic SPIIntr ); + // register map + localparam SPI_SCKDIV = 8'h00; + localparam SPI_SCKMODE = 8'h04; + localparam SPI_CSID = 8'h10; + localparam SPI_CSDEF = 8'h14; + localparam SPI_CSMODE = 8'h18; + localparam SPI_DELAY0 = 8'h28; + localparam SPI_DELAY1 = 8'h2C; + localparam SPI_FMT = 8'h40; + localparam SPI_TXDATA = 8'h48; + localparam SPI_RXDATA = 8'h4C; + localparam SPI_TXMARK = 8'h50; + localparam SPI_RXMARK = 8'h54; + localparam SPI_IE = 8'h70; + localparam SPI_IP = 8'h74; + // SPI control registers. Refer to SiFive FU540-C000 manual logic [11:0] SckDiv; logic [1:0] SckMode; @@ -61,7 +77,7 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( // Bus interface signals logic [7:0] Entry; logic Memwrite; - logic [31:0] Din, Dout; + logic [31:0] Din, Dout; logic TransmitInactive; // High when there is no transmission, used as hardware interlock signal // FIFO FSM signals @@ -130,8 +146,8 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( // -- Note SPI registers are 32 bits no matter what; access them with LW SW. assign Din = PWDATA[31:0]; - if (P.XLEN == 64) assign PRDATA = {Dout, Dout}; - else assign PRDATA = Dout; + if (P.XLEN == 64) assign PRDATA = { Dout, Dout}; + else assign PRDATA = Dout; // Register access always_ff@(posedge PCLK, negedge PRESETn) @@ -140,7 +156,7 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( SckMode <= 2'b0; ChipSelectID <= 2'b0; ChipSelectDef <= 4'b1111; - ChipSelectMode <= 0; + ChipSelectMode <= 2'b0; Delay0 <= {8'b1,8'b1}; Delay1 <= {8'b0,8'b1}; Format <= {5'b10000}; @@ -155,18 +171,18 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( /* verilator lint_off CASEINCOMPLETE */ if (Memwrite & TransmitInactive) case(Entry) // flop to sample inputs - 8'h00: SckDiv <= Din[11:0]; - 8'h04: SckMode <= Din[1:0]; - 8'h10: ChipSelectID <= Din[1:0]; - 8'h14: ChipSelectDef <= Din[3:0]; - 8'h18: ChipSelectMode <= Din[1:0]; - 8'h28: Delay0 <= {Din[23:16], Din[7:0]}; - 8'h2C: Delay1 <= {Din[23:16], Din[7:0]}; - 8'h40: Format <= {Din[19:16], Din[2]}; - 8'h48: if (~TransmitFIFOWriteFull) TransmitData[7:0] <= Din[7:0]; - 8'h50: TransmitWatermark <= Din[2:0]; - 8'h54: ReceiveWatermark <= Din[2:0]; - 8'h70: InterruptEnable <= Din[1:0]; + SPI_SCKDIV: SckDiv <= Din[11:0]; + SPI_SCKMODE: SckMode <= Din[1:0]; + SPI_CSID: ChipSelectID <= Din[1:0]; + SPI_CSDEF: ChipSelectDef <= Din[3:0]; + SPI_CSMODE: ChipSelectMode <= Din[1:0]; + SPI_DELAY0: Delay0 <= {Din[23:16], Din[7:0]}; + SPI_DELAY1: Delay1 <= {Din[23:16], Din[7:0]}; + SPI_FMT: Format <= {Din[19:16], Din[2]}; + SPI_TXDATA: if (~TransmitFIFOWriteFull) TransmitData[7:0] <= Din[7:0]; + SPI_TXMARK: TransmitWatermark <= Din[2:0]; + SPI_RXMARK: ReceiveWatermark <= Din[2:0]; + SPI_IE: InterruptEnable <= Din[1:0]; endcase /* verilator lint_off CASEINCOMPLETE */ @@ -176,21 +192,21 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( InterruptPending[1] <= RecieveWriteMark; case(Entry) // Flop to sample inputs - 8'h00: Dout <= {20'b0, SckDiv}; - 8'h04: Dout <= {30'b0, SckMode}; - 8'h10: Dout <= {30'b0, ChipSelectID}; - 8'h14: Dout <= {28'b0, ChipSelectDef}; - 8'h18: Dout <= {30'b0, ChipSelectMode}; - 8'h28: Dout <= {8'b0, Delay0[15:8], 8'b0, Delay0[7:0]}; - 8'h2C: Dout <= {8'b0, Delay1[15:8], 8'b0, Delay1[7:0]}; - 8'h40: Dout <= {12'b0, Format[4:1], 13'b0, Format[0], 2'b0}; - 8'h48: Dout <= {23'b0, TransmitFIFOWriteFull, 8'b0}; - 8'h4C: Dout <= {23'b0, ReceiveFIFOReadEmpty, ReceiveData[7:0]}; - 8'h50: Dout <= {29'b0, TransmitWatermark}; - 8'h54: Dout <= {29'b0, ReceiveWatermark}; - 8'h70: Dout <= {30'b0, InterruptEnable}; - 8'h74: Dout <= {30'b0, InterruptPending}; - default: Dout <= 32'b0; + SPI_SCKDIV: Dout <= {20'b0, SckDiv}; + SPI_SCKMODE: Dout <= {30'b0, SckMode}; + SPI_CSID: Dout <= {30'b0, ChipSelectID}; + SPI_CSDEF: Dout <= {28'b0, ChipSelectDef}; + SPI_CSMODE: Dout <= {30'b0, ChipSelectMode}; + SPI_DELAY0: Dout <= {8'b0, Delay0[15:8], 8'b0, Delay0[7:0]}; + SPI_DELAY1: Dout <= {8'b0, Delay1[15:8], 8'b0, Delay1[7:0]}; + SPI_FMT: Dout <= {12'b0, Format[4:1], 13'b0, Format[0], 2'b0}; + SPI_TXDATA: Dout <= {23'b0, TransmitFIFOWriteFull, 8'b0}; + SPI_RXDATA: Dout <= {23'b0, ReceiveFIFOReadEmpty, ReceiveData[7:0]}; + SPI_TXMARK: Dout <= {29'b0, TransmitWatermark}; + SPI_RXMARK: Dout <= {29'b0, ReceiveWatermark}; + SPI_IE: Dout <= {30'b0, InterruptEnable}; + SPI_IP: Dout <= {30'b0, InterruptPending}; + default: Dout <= 32'b0; endcase end @@ -200,8 +216,8 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( assign SCLKenable = (DivCounter == SckDiv); assign SCLKenableEarly = ((DivCounter + 12'b1) == SckDiv); always_ff @(posedge PCLK, negedge PRESETn) - if (~PRESETn) DivCounter <= 0; - else if (SCLKenable) DivCounter <= 0; + if (~PRESETn) DivCounter <= '0; + else if (SCLKenable) DivCounter <= 12'b0; else DivCounter <= DivCounter + 12'b1; // Asserts when transmission is one frame before complete @@ -219,11 +235,11 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( // Calculate tx/rx fifo write and recieve increment signals always_ff @(posedge PCLK, negedge PRESETn) - if (~PRESETn) TransmitFIFOWriteIncrement <= 0; + if (~PRESETn) TransmitFIFOWriteIncrement <= 1'b0; else TransmitFIFOWriteIncrement <= (Memwrite & (Entry == 8'h48) & ~TransmitFIFOWriteFull & TransmitInactive); always_ff @(posedge PCLK, negedge PRESETn) - if (~PRESETn) ReceiveFIFOReadIncrement <= 0; + if (~PRESETn) ReceiveFIFOReadIncrement <= 1'b0; else ReceiveFIFOReadIncrement <= ((Entry == 8'h4C) & ~ReceiveFIFOReadEmpty & PSEL & ~ReceiveFIFOReadIncrement); // Tx/Rx FIFOs @@ -233,14 +249,14 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( ReceiveData[7:0], ReceiveFIFOWriteFull, ReceiveFIFOReadEmpty, RecieveWriteMark, RecieveReadMark); always_ff @(posedge PCLK, negedge PRESETn) - if (~PRESETn) TransmitFIFOReadEmptyDelay <= 1; + if (~PRESETn) TransmitFIFOReadEmptyDelay <= 1'b1; else if (SCLKenable) TransmitFIFOReadEmptyDelay <= TransmitFIFOReadEmpty; always_ff @(posedge PCLK, negedge PRESETn) - if (~PRESETn) ReceiveShiftFullDelay <= 0; + if (~PRESETn) ReceiveShiftFullDelay <= 1'b0; else if (SCLKenable) ReceiveShiftFullDelay <= ReceiveShiftFull; always_ff @(posedge PCLK, negedge PRESETn) - if (~PRESETn) ReceiveShiftFullDelayPCLK <= 0; + if (~PRESETn) ReceiveShiftFullDelayPCLK <= 1'b0; else if (SCLKenableEarly) ReceiveShiftFullDelayPCLK <= ReceiveShiftFull; assign TransmitShiftRegLoad = ~TransmitShiftEmpty & ~Active | (((ChipSelectMode == 2'b10) & ~|(Delay1[15:8])) & ((ReceiveShiftFullDelay | ReceiveShiftFull) & ~SampleEdge & ~TransmitFIFOReadEmpty)); @@ -399,12 +415,11 @@ module SynchFIFO #(parameter M=3, N=8)( // 2^M entries of N bits // write and read are enabled always_ff @(posedge PCLK, negedge PRESETn) if (~PRESETn) begin - rptr <= 0; - wptr <= 0; + rptr <= '0; + wptr <= '0; wfull <= 1'b0; rempty <= 1'b1; - end - else begin + end else begin if (wen) begin wfull <= ({~wptrnext[M], wptrnext[M-1:0]} == rptr); wptr <= wptrnext; @@ -429,13 +444,13 @@ module TransmitShiftFSM( output logic TransmitShiftEmpty); always_ff @(posedge PCLK, negedge PRESETn) - if (~PRESETn) TransmitShiftEmpty <= 1; + if (~PRESETn) TransmitShiftEmpty <= 1'b1; else if (TransmitShiftEmpty) begin - if (TransmitFIFOReadEmpty | (~TransmitFIFOReadEmpty & (ReceivePenultimateFrame & Active0))) TransmitShiftEmpty <= 1; - else if (~TransmitFIFOReadEmpty) TransmitShiftEmpty <= 0; + if (TransmitFIFOReadEmpty | (~TransmitFIFOReadEmpty & (ReceivePenultimateFrame & Active0))) TransmitShiftEmpty <= 1'b1; + else if (~TransmitFIFOReadEmpty) TransmitShiftEmpty <= 1'b0; end else begin - if (ReceivePenultimateFrame & Active0) TransmitShiftEmpty <= 1; - else TransmitShiftEmpty <= 0; + if (ReceivePenultimateFrame & Active0) TransmitShiftEmpty <= 1'b1; + else TransmitShiftEmpty <= 1'b0; end endmodule diff --git a/src/uncore/uartPC16550D.sv b/src/uncore/uartPC16550D.sv index 94a587d9f..f93795be5 100644 --- a/src/uncore/uartPC16550D.sv +++ b/src/uncore/uartPC16550D.sv @@ -52,6 +52,16 @@ module uartPC16550D #(parameter UART_PRESCALE) ( output logic SOUT, RTSb, DTRb, OUT1b, OUT2b // UART external serial and flow-control outputs ); + // register map + localparam UART_DLL_RBR = 3'b000; + localparam UART_DLM_IER = 3'b001; + localparam UART_IIR = 3'b010; + localparam UART_LCR = 3'b011; + localparam UART_MCR = 3'b100; + localparam UART_LSR = 3'b101; + localparam UART_MSR = 3'b110; + localparam UART_SCR = 3'b111; + // transmit and receive states typedef enum logic [1:0] {UART_IDLE, UART_ACTIVE, UART_DONE, UART_BREAK} statetype; @@ -150,35 +160,35 @@ module uartPC16550D #(parameter UART_PRESCALE) ( if (~MEMWb) begin /* verilator lint_off CASEINCOMPLETE */ case (A) - 3'b000: if (DLAB) DLL <= Din; // else TXHR <= Din; // TX handled in TX register/FIFO section - 3'b001: if (DLAB) DLM <= Din; else IER <= Din[3:0]; - 3'b010: FCR <= {Din[7:6], 2'b0, Din[3], 2'b0, Din[0]}; // Write only FIFO Control Register; 4:5 reserved and 2:1 self-clearing - 3'b011: LCR <= Din; - 3'b100: MCR <= Din[4:0]; - 3'b111: SCR <= Din; + UART_DLL_RBR: if (DLAB) DLL <= Din; // else TXHR <= Din; // TX handled in TX register/FIFO section + UART_DLM_IER: if (DLAB) DLM <= Din; else IER <= Din[3:0]; + UART_IIR: FCR <= {Din[7:6], 2'b0, Din[3], 2'b0, Din[0]}; // Write only FIFO Control Register; 4:5 reserved and 2:1 self-clearing + UART_LCR: LCR <= Din; + UART_MCR: MCR <= Din[4:0]; + UART_SCR: SCR <= Din; endcase /* verilator lint_on CASEINCOMPLETE */ end // Line Status Register (8.6.3) // Ben 6/9/21 I don't like how this is a register. A lot of the individual bits have clocked components, so this just adds unecessary delay. - if (~MEMWb & (A == 3'b101)) + if (~MEMWb & (A == UART_LSR)) LSR[6:1] <= Din[6:1]; // recommended only for test, see 8.6.3 else begin LSR[0] <= rxdataready; // Data ready - LSR[1] <= (LSR[1] | RXBR[10]) & ~squashRXerrIP;; // overrun error - LSR[2] <= (LSR[2] | RXBR[9]) & ~squashRXerrIP; // parity error - LSR[3] <= (LSR[3] | RXBR[8]) & ~squashRXerrIP; // framing error - LSR[4] <= (LSR[4] | rxbreak) & ~squashRXerrIP; // break indicator + LSR[1] <= (LSR[1] | RXBR[10]) & ~squashRXerrIP; // overrun error + LSR[2] <= (LSR[2] | RXBR[9]) & ~squashRXerrIP; // parity error + LSR[3] <= (LSR[3] | RXBR[8]) & ~squashRXerrIP; // framing error + LSR[4] <= (LSR[4] | rxbreak) & ~squashRXerrIP; // break indicator LSR[5] <= THRE; // THRE LSR[6] <= ~txsrfull & THRE; // TEMT - if (rxfifohaserr) LSR[7] <= 1; // any bits in FIFO have error + if (rxfifohaserr) LSR[7] <= 1'b1; // any bits in FIFO have error end // Modem Status Register (8.6.8) - if (~MEMWb & (A == 3'b110)) + if (~MEMWb & (A == UART_MSR)) MSR <= Din[3:0]; - else if (~MEMRb & (A == 3'b110)) + else if (~MEMRb & (A == UART_MSR)) MSR <= 4'b0; // Reading MSR clears the flags in MSR bits 3:0 else begin MSR[0] <= MSR[0] | CTSb2 ^ CTSbsync; // Delta Clear to Send @@ -187,18 +197,18 @@ module uartPC16550D #(parameter UART_PRESCALE) ( MSR[3] <= MSR[3] | DCDb2 ^ DCDbsync; // Delta Data Carrier Detect end end + always_comb if (~MEMRb) case (A) - 3'b000: if (DLAB) Dout = DLL; else Dout = RBR[7:0]; - 3'b001: if (DLAB) Dout = DLM; else Dout = {4'b0, IER[3:0]}; - 3'b010: Dout = {{2{fifoenabled}}, 2'b00, intrID[2:0], ~intrpending}; // Read only Interupt Ident Register - 3'b011: Dout = LCR; - 3'b100: Dout = {3'b000, MCR}; - 3'b101: Dout = LSR; - // 3'b110: Dout = {~CTSbsync, ~DSRbsync, ~RIbsync, ~DCDbsync, MSR[3:0]}; - 3'b110: Dout = {~DCDbsync, ~RIbsync, ~DSRbsync, ~CTSbsync, MSR[3:0]}; - 3'b111: Dout = SCR; + UART_DLL_RBR: if (DLAB) Dout = DLL; else Dout = RBR[7:0]; + UART_DLM_IER: if (DLAB) Dout = DLM; else Dout = {4'b0, IER[3:0]}; + UART_IIR: Dout = {{2{fifoenabled}}, 2'b00, intrID[2:0], ~intrpending}; // Read only Interupt Ident Register + UART_LCR: Dout = LCR; + UART_MCR: Dout = {3'b000, MCR}; + UART_LSR: Dout = LSR; + UART_MSR: Dout = {~DCDbsync, ~RIbsync, ~DSRbsync, ~CTSbsync, MSR[3:0]}; + UART_SCR: Dout = SCR; endcase else Dout = 8'b0; @@ -215,7 +225,7 @@ module uartPC16550D #(parameter UART_PRESCALE) ( always_ff @(posedge PCLK, negedge PRESETn) if (~PRESETn) begin baudcount <= 1; - baudpulse <= 0; + baudpulse <= 1'b0; end else if (~MEMWb & DLAB & (A == 3'b0 | A == 3'b1)) begin baudcount <= 1; end else begin @@ -240,18 +250,18 @@ module uartPC16550D #(parameter UART_PRESCALE) ( always_ff @(posedge PCLK, negedge PRESETn) if (~PRESETn) begin - rxoversampledcnt <= 0; + rxoversampledcnt <= '0; rxstate <= UART_IDLE; - rxbitsreceived <= 0; - rxtimeoutcnt <= 0; + rxbitsreceived <= '0; + rxtimeoutcnt <= '0; end else begin if (rxstate == UART_IDLE & ~SINsync) begin // got start bit rxstate <= UART_ACTIVE; - rxoversampledcnt <= 0; - rxbitsreceived <= 0; - if (~rxfifotimeout) rxtimeoutcnt <= 0; // reset timeout when new character is arriving. Jacob Pease: Only if the timeout was not already reached. p.16 PC16550D.pdf + rxoversampledcnt <= '0; + rxbitsreceived <= '0; + if (~rxfifotimeout) rxtimeoutcnt <= '0; // reset timeout when new character is arriving. Jacob Pease: Only if the timeout was not already reached. p.16 PC16550D.pdf end else if (rxbaudpulse & (rxstate == UART_ACTIVE)) begin - rxoversampledcnt <= rxoversampledcnt + 1; // 16x oversampled counter + rxoversampledcnt <= rxoversampledcnt + 4'b1; // 16x oversampled counter if (rxcentered) rxbitsreceived <= rxbitsreceived + 1; if (rxbitsreceived == rxbitsexpected) rxstate <= UART_DONE; // pulse rxdone for a cycle end else if (rxstate == UART_DONE | rxstate == UART_BREAK) begin @@ -259,7 +269,7 @@ module uartPC16550D #(parameter UART_PRESCALE) ( else rxstate <= UART_IDLE; end // timeout counting - if (~MEMRb & A == 3'b000 & ~DLAB) rxtimeoutcnt <= 0; // reset timeout on read + if (~MEMRb & A == 3'b000 & ~DLAB) rxtimeoutcnt <= '0; // reset timeout on read else if (fifoenabled & ~rxfifoempty & rxbaudpulse & ~rxfifotimeout) rxtimeoutcnt <= rxtimeoutcnt+1; // may not be right end @@ -295,32 +305,32 @@ module uartPC16550D #(parameter UART_PRESCALE) ( // receive FIFO and register always_ff @(posedge PCLK) if (~PRESETn) begin - rxfifohead <= 0; rxfifotail <= 0; rxdataready <= 0; RXBR <= 0; + rxfifohead <= '0; rxfifotail <= '0; rxdataready <= 1'b0; RXBR <= '0; end else begin if (~MEMWb & (A == 3'b010) & Din[1]) begin - rxfifohead <= 0; rxfifotail <= 0; rxdataready <= 0; + rxfifohead <= '0; rxfifotail <= '0; rxdataready <= 1'b0; end else if (rxstate == UART_DONE) begin RXBR <= {rxoverrunerr, rxparityerr, rxframingerr, rxdata}; // load recevive buffer register - if (rxoverrunerr) $warning("UART RX Overrun Err\n"); - if (rxparityerr) $warning("UART RX Parity Err\n"); - if (rxframingerr) $warning("UART RX Framing Err\n"); +// if (rxoverrunerr) $warning("UART RX Overrun Err\n"); +// if (rxparityerr) $warning("UART RX Parity Err\n"); +// if (rxframingerr) $warning("UART RX Framing Err\n"); if (fifoenabled) begin rxfifo[rxfifohead] <= {rxoverrunerr, rxparityerr, rxframingerr, rxdata}; - rxfifohead <= rxfifohead + 1; + rxfifohead <= rxfifohead + 1'b1; end - rxdataready <= 1; + rxdataready <= 1'b1; end else if (~MEMRb & A == 3'b000 & ~DLAB) begin // reading RBR updates ready / pops fifo if (fifoenabled) begin if (~rxfifoempty) rxfifotail <= rxfifotail + 1; - // if (rxfifoempty) rxdataready <= 0; - if (rxfifoentries == 1) rxdataready <= 0; // When reading the last entry, data ready becomes zero + // if (rxfifoempty) rxdataready <= 1'b0; + if (rxfifoentries == 1) rxdataready <= 1'b0; // When reading the last entry, data ready becomes zero end else begin - rxdataready <= 0; + rxdataready <= 1'b0; RXBR <= {1'b0, RXBR[9:0]}; // Ben 31 March 2022: I added this so that rxoverrunerr permanently goes away upon reading RBR (when not in FIFO mode) end end else if (~MEMWb & A == 3'b010) // writes to FIFO Control Register if (Din[1] | ~Din[0]) begin // rx FIFO reset or FIFO disable clears FIFO contents - rxfifohead <= 0; rxfifotail <= 0; + rxfifohead <= '0; rxfifotail <= '0; end end @@ -354,9 +364,9 @@ module uartPC16550D #(parameter UART_PRESCALE) ( // receive buffer register and ready bit always_ff @(posedge PCLK, negedge PRESETn) // track rxrdy for DMA mode (FCR3 = FCR0 = 1) - if (~PRESETn) rxfifodmaready <= 0; - else if (rxfifotriggered | rxfifotimeout) rxfifodmaready <= 1; - else if (rxfifoempty) rxfifodmaready <= 0; + if (~PRESETn) rxfifodmaready <= 1'b0; + else if (rxfifotriggered | rxfifotimeout) rxfifodmaready <= 1'b1; + else if (rxfifoempty) rxfifodmaready <= 1'b0; always_comb if (fifoenabled) begin @@ -375,17 +385,17 @@ module uartPC16550D #(parameter UART_PRESCALE) ( always_ff @(posedge PCLK, negedge PRESETn) if (~PRESETn) begin - txoversampledcnt <= 0; + txoversampledcnt <= '0; txstate <= UART_IDLE; - txbitssent <= 0; + txbitssent <= '0; end else if ((txstate == UART_IDLE) & txsrfull) begin // start transmitting txstate <= UART_ACTIVE; - txoversampledcnt <= 1; - txbitssent <= 0; + txoversampledcnt <= 4'b1; + txbitssent <= '0; end else if (txbaudpulse & (txstate == UART_ACTIVE)) begin - txoversampledcnt <= txoversampledcnt + 1; + txoversampledcnt <= txoversampledcnt + 1'b1; if (txnextbit) begin // transmit at end of phase - txbitssent <= txbitssent+1; + txbitssent <= txbitssent + 1'b1; if (txbitssent == txbitsexpected) txstate <= UART_DONE; end end else if (txstate == UART_DONE) begin @@ -423,17 +433,17 @@ module uartPC16550D #(parameter UART_PRESCALE) ( // registers & FIFO always_ff @(posedge PCLK, negedge PRESETn) if (~PRESETn) begin - txfifohead <= 0; txfifotail <= 0; txhrfull <= 0; txsrfull <= 0; TXHR <= 0; txsr <= 12'hfff; + txfifohead <= '0; txfifotail <= '0; txhrfull <= 1'b0; txsrfull <= 1'b0; TXHR <= '0; txsr <= 12'hfff; end else if (~MEMWb & (A == 3'b010) & Din[2]) begin - txfifohead <= 0; txfifotail <= 0; + txfifohead <= '0; txfifotail <= '0; end else begin if (~MEMWb & A == 3'b000 & ~DLAB) begin // writing transmit holding register or fifo if (fifoenabled) begin txfifo[txfifohead] <= Din; - txfifohead <= txfifohead + 1; + txfifohead <= txfifohead + 4'b1; end else begin TXHR <= Din; - txhrfull <= 1; + txhrfull <= 1'b1; end $write("%c",Din); // for testbench end @@ -442,18 +452,18 @@ module uartPC16550D #(parameter UART_PRESCALE) ( if (~txfifoempty & ~txsrfull) begin txsr <= txdata; txfifotail <= txfifotail+1; - txsrfull <= 1; + txsrfull <= 1'b1; end end else if (txhrfull) begin txsr <= txdata; - txhrfull <= 0; - txsrfull <= 1; + txhrfull <= 1'b0; + txsrfull <= 1'b1; end - end else if (txstate == UART_DONE) txsrfull <= 0; // done transmitting shift register + end else if (txstate == UART_DONE) txsrfull <= 1'b0; // done transmitting shift register else if (txstate == UART_ACTIVE & txnextbit) txsr <= {txsr[10:0], 1'b1}; // shift txhr if (!MEMWb & A == 3'b010) // writes to FIFO control register if (Din[2] | ~Din[0]) begin // tx FIFO reste or FIFO disable clears FIFO contents - txfifohead <= 0; txfifotail <= 0; + txfifohead <= '0; txfifotail <= '0; end end @@ -483,9 +493,9 @@ module uartPC16550D #(parameter UART_PRESCALE) ( // transmit buffer ready bit always_ff @(posedge PCLK, negedge PRESETn) // track txrdy for DMA mode (FCR3 = FCR0 = 1) - if (~PRESETn) txfifodmaready <= 0; - else if (txfifoempty) txfifodmaready <= 1; - else if (txfifofull) txfifodmaready <= 0; + if (~PRESETn) txfifodmaready <= 1'b0; + else if (txfifoempty) txfifodmaready <= 1'b1; + else if (txfifofull) txfifodmaready <= 1'b0; always_comb if (fifoenabled & fifodmamodesel) TXRDYb = ~txfifodmaready; @@ -493,7 +503,7 @@ module uartPC16550D #(parameter UART_PRESCALE) ( // Transmitter pin assign SOUTbit = txsr[11]; // transmit most significant bit - assign SOUT = loop ? 1 : (LCR[6] ? 0 : SOUTbit); // tied to 1 during loopback or 0 during break + assign SOUT = loop ? 1 : (LCR[6] ? '0 : SOUTbit); // tied to 1 during loopback or 0 during break /////////////////////////////////////////// // interrupts @@ -509,7 +519,7 @@ module uartPC16550D #(parameter UART_PRESCALE) ( // IIR: interrupt priority (Table 5) // set intrID based on highest priority pending interrupt source; otherwise, no interrupt is pending always_comb begin - intrpending = 1; + intrpending = 1'b1; if (RXerrIP & IER[2]) intrID = 3'b011; else if (rxdataavailintr & IER[0]) intrID = 3'b010; else if (rxfifotimeout & fifoenabled & IER[0]) intrID = 3'b110; @@ -517,7 +527,7 @@ module uartPC16550D #(parameter UART_PRESCALE) ( else if (modemstatusintr & IER[3]) intrID = 3'b000; else begin intrID = 3'b000; - intrpending = 0; + intrpending = 1'b0; end end always_ff @(posedge PCLK) INTR <= intrpending; // prevent glitches on interrupt pin @@ -549,10 +559,10 @@ module uartPC16550D #(parameter UART_PRESCALE) ( assign fifodmamodesel = FCR[3]; always_comb case (FCR[7:6]) - 2'b00: rxfifotriggerlevel = 1; - 2'b01: rxfifotriggerlevel = 4; - 2'b10: rxfifotriggerlevel = 8; - 2'b11: rxfifotriggerlevel = 14; + 2'b00: rxfifotriggerlevel = 4'd1; + 2'b01: rxfifotriggerlevel = 4'd4; + 2'b10: rxfifotriggerlevel = 4'd8; + 2'b11: rxfifotriggerlevel = 4'd14; endcase endmodule