blob: 16e6dce7941722bd95fac552dde22c9214d390a8 [file] [log] [blame]
//Listing 8.3
module uart_tx
#(
parameter DBIT = 8, // # data bits
SB_TICK = 16 // # ticks for stop bits
)
(
input wire clk, reset,
input wire tx_start, s_tick,
input wire [7:0] din,
output reg tx_done_tick,
output wire tx
);
// symbolic state declaration
localparam [1:0]
idle = 2'b00,
start = 2'b01,
data = 2'b10,
stop = 2'b11;
// signal declaration
reg [1:0] state_reg, state_next;
reg [3:0] s_reg, s_next;
reg [2:0] n_reg, n_next;
reg [7:0] b_reg, b_next;
reg tx_reg, tx_next;
// body
// FSMD state & data registers
always @(posedge clk, posedge reset)
if (reset)
begin
state_reg <= idle;
s_reg <= 0;
n_reg <= 0;
b_reg <= 0;
tx_reg <= 1'b1;
end
else
begin
state_reg <= state_next;
s_reg <= s_next;
n_reg <= n_next;
b_reg <= b_next;
tx_reg <= tx_next;
end
// FSMD next-state logic & functional units
always @*
begin
state_next = state_reg;
tx_done_tick = 1'b0;
s_next = s_reg;
n_next = n_reg;
b_next = b_reg;
tx_next = tx_reg ;
case (state_reg)
idle:
begin
tx_next = 1'b1;
if (tx_start)
begin
state_next = start;
s_next = 0;
b_next = din;
end
end
start:
begin
tx_next = 1'b0;
if (s_tick)
if (s_reg==15)
begin
state_next = data;
s_next = 0;
n_next = 0;
end
else
s_next = s_reg + 1;
end
data:
begin
tx_next = b_reg[0];
if (s_tick)
if (s_reg==15)
begin
s_next = 0;
b_next = b_reg >> 1;
if (n_reg==(DBIT-1))
state_next = stop ;
else
n_next = n_reg + 1;
end
else
s_next = s_reg + 1;
end
stop:
begin
tx_next = 1'b1;
if (s_tick)
if (s_reg==(SB_TICK-1))
begin
state_next = idle;
tx_done_tick = 1'b1;
end
else
s_next = s_reg + 1;
end
endcase
end
// output
assign tx = tx_reg;
endmodule