Skip to content

Instantly share code, notes, and snippets.

@buttercutter
Last active June 6, 2017 12:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save buttercutter/8966ac00db796ede35fa82512053f7ba to your computer and use it in GitHub Desktop.
Save buttercutter/8966ac00db796ede35fa82512053f7ba to your computer and use it in GitHub Desktop.
Tx UART in verilog
module Tx_TOP(clk, reset, start, i_data, serial_out) // UART transmitter : parallel input, serial output
input clk; // 48MHz
input reset;
input start; // i_data is valid, so start transmission
input[7:0] i_data;
output serial_out;
wire baud_out; // 16*baudrate clock
wire serial_data; // output from serializer (TxUART)
TxUART tx (.clk(baud_out), .reset(0), .start_tx(start), .i_data(i_data), .o_data(serial_data));
baud_generator bg (.clk(clk), .baud_out(baud_out));
shift_register sreg (.clk(baud_out), .reset(0), .data_in(serial_data), .data_out(serial_out));
// FIFO tx_fifo (clk, reset, enqueue, dequeue, flush, i_value, almost_full, almost_empty, o_value);
endmodule
// credit: Adapted from http://zipcpu.com/blog/2017/06/02/generating-timing.html
module (clk, baud_out) // we are trying to obtain baud_out = clk/(9600*16)
input clk;
output baud_out;
wire ck_stb;
reg[17:0] counter;
always @(posedge clk)
{ck_stb, counter} <= counter + 18'd(9600 << 4); // 9600 * 16
assign baud_out = ck_stb;
endmodule
`define Tx_IDLE_BIT 0;
`define Tx_START_BIT 1;
`define Tx_DATA_BITS < `Tx_PARITY_BIT;
`define Tx_PARITY_BIT 10;
`define Tx_STOP_BIT 11;
module TxUART(clk, reset, start_tx, i_data, o_data)
input clk, reset, start_tx;
input[7:0] i_data;
output reg o_data;
reg[3:0] state, next_state;
wire parity_bit;
always @(posedge clk)
begin
if (reset)
state <= `Tx_IDLE_BIT;
else
state <= next_state;
end
always @(*)
begin : tx_fsm
case(state)
`Tx_IDLE_BIT : next_state = (start_tx == 1) ? Tx_START_BIT : `Tx_IDLE_BIT;
o_data = 1;
`Tx_START_BIT : next_state = `Tx_DATA_BIT;
o_data = 0;
`Tx_DATA_BITS : next_state = state + 1;
o_data = i_data[state-2];
`Tx_PARITY_BIT : next_state = `Tx_STOP_BIT;
o_data = parity_bit;
`Tx_STOP_BIT : next_state = `Tx_IDLE_BIT;
o_data = 1;
default : next_state = `Tx_IDLE_BIT;
o_data = 1;
endcase
end
assign parity_bit = ^i_data; // even parity http://www.asic-world.com/examples/verilog/parity.html
endmodule
// credit: Adapted from http://zipcpu.com/blog/2017/06/02/generating-timing.html
module baud_generator(clk, baud_out) // we are trying to obtain baud_out = clk/(9600*16)
input clk;
output baud_out;
wire ck_stb;
reg[17:0] counter;
always @(posedge clk)
{ck_stb, counter} <= counter + 18'd(9600 << 4); // 9600 * 16
assign baud_out = ck_stb;
endmodule
// Credit: Adapted from http://www.referencedesigner.com/tutorials/verilog/verilog_32.php
module shift_register(clk, reset, data_in, data_out) // cascade of 10 registers
parameter N=10;
input wire clk, reset;
input wire data_in;
output wire data_out;
reg [N-1:0] r_reg;
wire [N-1:0] r_next;
always @(posedge clk)
begin
if (reset)
r_reg <= 0;
else
r_reg <= r_next;
end
assign r_next = {data_in, r_reg[N-1:1]};
assign data_out = r_reg[0];
endmodule
// Adapted from https://github.com/jbush001/NyuziProcessor/blob/master/hardware/core/sync_fifo.sv
module FIFO (clk, reset, enqueue, dequeue, flush, i_value, almost_full, almost_empty, o_value)
input clk, reset, enqueue, dequeue, flush, i_value;
output almost_full, almost_empty, o_value;
parameter SIZE = 22;
parameter ALMOST_FULL_THRESHOLD = SIZE;
parameter ALMOST_EMPTY_THRESHOLD = 1);
reg[4:0] head, tail, count;
assign almost_full = count >= ALMOST_FULL_THRESHOLD;
assign almost_empty = count >= ALMOST_EMPTY_THRESHOLD;
assign o_value = data[head];
always @(posedge clk)
begin
if (reset) begin
head <= 0;
tail <= 0;
count <= 0;
end
else begin
if (flush) begin
head <= 0;
tail <= 0;
count <= 0;
end
else begin
if (enqueue) begin
tail <= tail + 1;
data[tail] <= i_value;
end
if (dequeue) begin
head <= head + 1;
end
if (enqueue && !dequeue)
count <= count + 1;
else if (dequeue && !enqueue)
count <= count - 1;
end
end
end
endmodule
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment