uart.v
`timescale 1ns / 1ps
module uart (
input clk,
input reset,
input tx_start,
input [7:0] tx_data,
output tx,
output tx_done
);
wire w_br_tick;
buadrate_generator U_BR_GEN (
.clk(clk),
.reset(reset),
.br_tick(w_br_tick)
);
transmitter U_TxD (
.clk(clk),
.reset(reset),
.br_tick(w_br_tick),
.tx_start(tx_start),
.tx_data(tx_data),
.tx(tx),
.tx_done(tx_done)
);
endmodule
module buadrate_generator (
input clk,
input reset,
output br_tick
);
reg [$clog2(100_000_000 / 9600)-1:0] counter_reg, counter_next;
reg tick_reg, tick_next;
assign br_tick = tick_reg;
always @(posedge clk, posedge reset) begin
if (reset) begin
counter_reg <= 0;
tick_reg = 1'b0;
end else begin
counter_reg <= counter_next;
tick_reg = tick_next;
end
end
always @(*) begin
if(counter_reg == 100_000_000 / 9600 -1) begin // comportmaster
//if (counter_reg == 10 - 1) begin // for simulation
counter_next = 0;
tick_next = 1'b1;
end else begin
counter_next = counter_reg + 1;
tick_next = 1'b0;
end
end
endmodule
module transmitter (
input clk,
input reset,
input br_tick,
input tx_start,
input [7:0] tx_data,
output tx,
output tx_done
);
localparam IDLE = 0, START = 1, DATA = 2, STOP = 3; // state
reg [1:0] state, state_next;
reg [7:0] tx_data_reg, tx_data_next;
reg [2:0] bit_cnt_reg, bit_cnt_next; // DATA bit count
reg tx_reg, tx_next;
reg tx_done_reg, tx_done_next;
// output logic
assign tx = tx_reg;
assign tx_done = tx_done_reg;
// state register
always @(posedge clk, posedge reset) begin
if (reset) begin
state <= IDLE;
tx_data_reg <= 0;
bit_cnt_reg <= 0;
tx_reg <= 1'b1;
tx_done_reg <= 1'b0;
end else begin
state <= state_next;
tx_data_reg <= tx_data_next;
bit_cnt_reg <= bit_cnt_next;
tx_reg <= tx_next;
tx_done_reg <= tx_done_next;
end
end
// next state combinational logic
always @(*) begin
state_next = state;
tx_done_next = tx_done_reg;
tx_data_next = tx_data_reg;
tx_next = tx_reg;
bit_cnt_next = bit_cnt_reg;
case (state)
IDLE: begin
tx_next = 1'b1;
tx_done_next = 1'b0;
if (tx_start) begin
tx_data_next = tx_data;
bit_cnt_next = 0;
state_next = START;
end
end
START: begin
tx_next = 1'b0;
if (br_tick)
state_next = DATA; // baudrate start later START state
end
DATA: begin
tx_next = tx_data_reg[0]; // send from LSB
if (br_tick) begin
if (bit_cnt_reg == 7) begin
state_next = STOP;
end else begin
bit_cnt_next = bit_cnt_reg + 1;
tx_data_next = {
1'b0, tx_data_reg[7:1]
}; // right shift register
end
end
end
STOP: begin
tx_next = 1'b1;
if (br_tick) begin
state_next = IDLE;
tx_done_next = 1'b1;
end
end
endcase
end
endmodule
top.v
`timescale 1ns / 1ps
module top(
input clk,
input reset,
input btn_tx_start,
output txd
);
wire w_btn_tx_start;
button U_BTN_TX(
.clk(clk),
.in(btn_tx_start),
.out(w_btn_tx_start)
);
uart U_UART(
.clk(clk),
.reset(reset),
.tx_start(w_btn_tx_start),
.tx_data(8'h41), // 'A'
.tx(txd),
.tx_done() // non-connect
);
endmodule
button.v
`timescale 1ns / 1ps
module button (
input clk,
input in,
output out
);
localparam N = 64; // shift 횟수
wire w_debounce_out;
reg [N-1 : 0] Q_reg, Q_next;
reg [1:0] dff_reg, dff_next;
// Output logic
assign out = ~dff_reg[0] & dff_reg[1];
always @(posedge clk) begin
Q_reg <= Q_next;
dff_reg <= dff_next;
end
// Next state logic
always @(*) begin
Q_next = {Q_reg[N-2:0], in}; // debounce circuit, left shift
end
assign w_debounce_out = &Q_reg;
always @(*) begin
dff_next[0] = w_debounce_out; // D-F/F
dff_next[1] = dff_reg[0];
end
endmodule
tb_uart
`timescale 1ns / 1ps
module tb_uart();
reg clk;
reg reset;
reg tx_start;
reg [7:0] tx_data;
wire tx;
wire tx_done;
uart dut(
.clk(clk),
.reset(reset),
.tx_start(tx_start),
.tx_data(tx_data),
.tx(tx),
.tx_done(tx_done)
);
always #5 clk = ~clk;
initial begin
clk = 1'b0;
reset = 1'b1;
tx_start = 1'b0;
tx_data = 0;
end
initial begin
#100 reset = 1'b0;
#100 tx_start = 1'b1; tx_data = 8'b11001010;
#10 tx_start = 1'b0;
end
endmodule
schematic
simulation
constraint
##7 segment display
set_property -dict { PACKAGE_PIN W7 IOSTANDARD LVCMOS33 } [get_ports { switch }]; #IO_L13P_T2_MRCC_34 ,Sch=CA
##Buttons
set_property -dict { PACKAGE_PIN U18 IOSTANDARD LVCMOS33 } [get_ports { reset }]; #IO_L18N_T2_A11_D27_14 ,Sch=BTNC
set_property -dict { PACKAGE_PIN T18 IOSTANDARD LVCMOS33 } [get_ports { btn_tx_start }]; #IO_L17N_T2_A13_D29_14 ,Sch=BTNU
#set_property -dict { PACKAGE_PIN W19 IOSTANDARD LVCMOS33 } [get_ports { fndSel[1] }]; #IO_L16N_T2_A15_D31_14 ,Sch=BTNL
#set_property -dict { PACKAGE_PIN T17 IOSTANDARD LVCMOS33 } [get_ports { fndSel[0] }]; #IO_L17P_T2_A14_D30_14 ,Sch=BTNR
#set_property -dict { PACKAGE_PIN U17 IOSTANDARD LVCMOS33 } [get_ports { }]; #IO_L18P_T2_A12_D28_14 ,Sch=BTND
##USB-RS232 Interface
#set_property -dict { PACKAGE_PIN B18 IOSTANDARD LVCMOS33 } [get_ports { RsRx }]; #IO_L19P_T3_16 ,Sch=UART_RXD_IN
set_property -dict { PACKAGE_PIN A18 IOSTANDARD LVCMOS33 } [get_ports { txd }]; #IO_L19N_T3_VREF_16 ,Sch=UART_TXD_OUT
video
'[하만]세미콘 아카데미 > verilog' 카테고리의 다른 글
0520 oversampling, uart (0) | 2024.06.22 |
---|---|
0517 uart_tx_rx (0) | 2024.06.22 |
0516 UART (0) | 2024.06.22 |
0516 upCounter_FSM (0) | 2024.06.22 |
0514 upCounter_FND_FSM (0) | 2024.06.22 |