f4pga-examples/xc7/additional_examples/uart_transmitter/transmitter.sv

135 lines
3.3 KiB
Systemverilog
Raw Normal View History

`timescale 1ns / 1ps
`default_nettype none
module tx(
input wire logic clk, Reset, Send,
input wire logic[7:0] Din,
output logic Sent, Sout
);
logic timerDone, clrTimer;
logic bitDone, incBit, clrBit;
logic startBit, dataBit, parityBit;
logic[2:0] bitNum;
logic[12:0] baudCount;
typedef enum logic[2:0] {START, BITS, PAR, STOP, ACK, IDLE, ERR = 'X} StateType;
StateType ns, cs;
always_ff @(posedge clk)
begin
if (startBit)
Sout <= 0;
else if (dataBit)
Sout <= Din[bitNum];
else if (parityBit)
Sout <= ~^Din;
else
Sout <= 1;
end
always_ff @(posedge clk)
begin
if (clrTimer)
baudCount <= 0;
else if (timerDone)
baudCount <= 0;
else
baudCount <= baudCount + 1'b1;
end
always_comb
begin
if (baudCount == 13'd5208)
timerDone = 1'b1;
else
timerDone = 1'b0;
end
always_ff @(posedge clk)
begin
if (clrBit)
bitNum <= 3'b000;
else if (incBit)
bitNum <= bitNum + 1'b1;
end
always_comb
begin
if (bitNum == 3'b111)
bitDone = 1'b1;
else
bitDone = 1'b0;
end
always_comb
begin
ns = ERR;
clrTimer = 0;
startBit = 0;
clrBit = 0;
dataBit = 0;
incBit = 0;
parityBit = 0;
Sent = 0;
if (Reset)
ns = IDLE;
else
case (cs)
IDLE: begin
clrTimer = 1'b1;
if (Send)
ns = START;
else
ns = IDLE;
end
START: begin
startBit = 1'b1;
if (timerDone)
begin
clrBit = 1'b1;
ns = BITS;
end
else
ns = START;
end
BITS: begin
dataBit = 1'b1;
if (timerDone && ~bitDone)
begin
incBit = 1'b1;
ns = BITS;
end
else if (timerDone && bitDone)
ns = PAR;
else
ns = BITS;
end
PAR: begin
parityBit = 1'b1;
if (timerDone)
ns = STOP;
else
ns = PAR;
end
STOP: if (timerDone)
ns = ACK;
else
ns = STOP;
ACK: begin
Sent = 1'b1;
if (~Send)
ns = IDLE;
else
ns = ACK;
end
endcase
end
always_ff @(posedge clk)
cs <= ns;
endmodule