|
@@ -5,20 +5,30 @@
|
|
|
// Currently only transmit is supported, 8-N-1, at a fixed speed.
|
|
|
// The baud rate is tty_clk/((divisor+1)*16).
|
|
|
//
|
|
|
-// Currently there is no overrun checking or interrupt support, but that
|
|
|
-// can come later. A large FIFO makes that less of an issue anyway...
|
|
|
+// The registers are as follows:
|
|
|
//
|
|
|
+// 0 - WO - data register (will be RW)
|
|
|
+// 1 - RW - baud rate register (binary fraction of TTY_CLK/16 - 1)
|
|
|
+// 2 - RO - status register
|
|
|
+// 0 - transmitter idle (FIFO and shift register empty)
|
|
|
+// 1 - transmit FIFO 3/4 empty
|
|
|
+// 2 - transmit FIFO 1/2 empty
|
|
|
+// 3 - transmit FIFO 1/2 full (inverse of bit 2)
|
|
|
+// 4 - transmit FIFO 3/4 full
|
|
|
+// 3 - RW - interrupt enable register (status register mask)
|
|
|
|
|
|
module tty (
|
|
|
- input rst_n,
|
|
|
- input clk,
|
|
|
+ input rst_n,
|
|
|
+ input clk,
|
|
|
|
|
|
- input valid,
|
|
|
- input [3:0] wstrb,
|
|
|
- input [31:0] wdata,
|
|
|
- input [0:0] addr,
|
|
|
+ input valid,
|
|
|
+ input [3:0] wstrb,
|
|
|
+ input [31:0] wdata,
|
|
|
+ input [1:0] addr,
|
|
|
+ output reg [31:0] rdata,
|
|
|
+ output reg irq,
|
|
|
|
|
|
- output tty_txd
|
|
|
+ output tty_txd
|
|
|
);
|
|
|
|
|
|
`include "functions.sv" // For ModelSim
|
|
@@ -53,6 +63,7 @@ module tty (
|
|
|
wire tx_wrreq;
|
|
|
wire tx_rdempty;
|
|
|
wire [7:0] tx_data;
|
|
|
+ wire [8:0] tx_usedw;
|
|
|
|
|
|
fifo txfifo (
|
|
|
.aclr ( ~rst_n ),
|
|
@@ -64,30 +75,9 @@ module tty (
|
|
|
.empty ( tx_rdempty ),
|
|
|
.full ( ),
|
|
|
.q ( tx_data ),
|
|
|
- .usedw ( )
|
|
|
+ .usedw ( tx_usedw )
|
|
|
);
|
|
|
|
|
|
- //
|
|
|
- // CPU -> transmitter data. No wait state is needed nor expected.
|
|
|
- //
|
|
|
-
|
|
|
- // Data mask (if/when needed)
|
|
|
- wire [31:0] wmask = {{8{wstrb[3]}}, {8{wstrb[2]}},
|
|
|
- {8{wstrb[1]}}, {8{wstrb[0]}}};
|
|
|
-
|
|
|
- // Data (FIFO) register; normally addressed as byte
|
|
|
- // Protect against long pulses (edge detect)
|
|
|
- reg old_wstrb;
|
|
|
- always @(posedge clk)
|
|
|
- old_wstrb <= wstrb[0];
|
|
|
-
|
|
|
- assign tx_wrreq = valid & wstrb[0] & ~old_wstrb & (addr == 0);
|
|
|
-
|
|
|
- // Divisor register
|
|
|
- always @(posedge clk)
|
|
|
- if (wstrb[0] & valid & (addr == 1))
|
|
|
- divisor <= wdata[NCO_BITS-1:0] & wmask;
|
|
|
-
|
|
|
//
|
|
|
// Transmitter
|
|
|
//
|
|
@@ -135,4 +125,63 @@ module tty (
|
|
|
end // if (tx_phase == 4'hF)
|
|
|
end // if ( tty_clk_en )
|
|
|
end // else: !if(~rst_n)
|
|
|
+
|
|
|
+ //
|
|
|
+ // CPU interface
|
|
|
+ //
|
|
|
+
|
|
|
+ // Data (FIFO) register; normally addressed as byte
|
|
|
+ // Protect against long pulses (edge detect)
|
|
|
+ reg old_wstrb;
|
|
|
+ always @(posedge clk)
|
|
|
+ old_wstrb <= wstrb[0];
|
|
|
+
|
|
|
+ assign tx_wrreq = valid & wstrb[0] & ~old_wstrb & (addr == 2'b00);
|
|
|
+
|
|
|
+ // Status register definition
|
|
|
+ localparam status_bits = 5;
|
|
|
+
|
|
|
+ wire [status_bits-1:0] status;
|
|
|
+
|
|
|
+ assign status[0] = tx_rdempty & (tx_bits == 4'd0);
|
|
|
+ assign status[1] = tx_usedw[8:7] == 2'b00;
|
|
|
+ assign status[2] = ~tx_usedw[8];
|
|
|
+ assign status[3] = tx_usedw[8];
|
|
|
+ assign status[4] = tx_usedw[8:7] == 2'b11;
|
|
|
+
|
|
|
+ reg [status_bits-1:0] irq_en;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Control register writes.
|
|
|
+ // Only full word writes are supported.
|
|
|
+ //
|
|
|
+ always @(negedge rst_n or posedge clk)
|
|
|
+ if (~rst_n)
|
|
|
+ begin
|
|
|
+ irq_en <= 5'b0;
|
|
|
+ end
|
|
|
+ else if (valid & (&wstrb))
|
|
|
+ case (addr)
|
|
|
+ 2'b01: divisor <= wdata[NCO_BITS-1:0];
|
|
|
+ 2'b11: irq_en <= wdata[status_bits-1:0];
|
|
|
+ endcase // case (addr)
|
|
|
+
|
|
|
+ // Read MUX
|
|
|
+ always @(*)
|
|
|
+ begin
|
|
|
+ rdata = 32'b0;
|
|
|
+ case (addr)
|
|
|
+ 2'b01: rdata = divisor;
|
|
|
+ 2'b10: rdata = status;
|
|
|
+ 2'b11: rdata = irq_en;
|
|
|
+ endcase // case (addr)
|
|
|
+ end
|
|
|
+
|
|
|
+ // Interrupt
|
|
|
+ always @(negedge rst_n or posedge clk)
|
|
|
+ if (~rst_n)
|
|
|
+ irq <= 1'b0;
|
|
|
+ else
|
|
|
+ irq <= |(status & irq_en);
|
|
|
+
|
|
|
endmodule // tty
|