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;i
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.
+ 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