[2024.05.20.월] 인천인력개발원 하만 세미콘 아카데미
실습 1: uart_rx
1. uart_rx_cntl.v Design Sources 생성

2. 코드 작성
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2024/05/20 12:06:26
// Design Name:
// Module Name: uart_rx_cntl
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module uart_rx_cntl(
input RST,
input CLK,
input RXD,
input BAUD_X16_EN,
input bit_cnt_done,
output reg [1:0] fsm_state
);
localparam [1:0] idle = 2'b00,
start= 2'b01,
data = 2'b10,
stop = 2'b11;
reg [1:0] curr_state, next_state;
wire over_sample_cnt_done;
reg [3:0] over_sample_cnt;
always @(posedge CLK)
begin
if(RST)
curr_state <= idle;
else
curr_state <= next_state;
end
always @(curr_state, over_sample_cnt_done, bit_cnt_done, RXD)
begin
case (curr_state)
idle : begin
if(RXD == 1'b0)
next_state = start;
else
next_state = idle;
fsm_state = 2'b00;
end
start : begin
if(over_sample_cnt_done) begin
if(RXD)
next_state = idle;
else
next_state = data;
end
fsm_state = 2'b01;
end
data : begin
if(over_sample_cnt_done && bit_cnt_done)
next_state = stop;
else
next_state = data;
fsm_state = 2'b10;
end
stop : begin
if(over_sample_cnt_done)
next_state = idle;
else
next_state= stop;
fsm_state = 2'b11;
end
default : next_state = idle;
endcase
end
//over sample count
always @(posedge CLK)
begin
if(RST || curr_state == idle)
over_sample_cnt <= 4'd7;
else if(BAUD_X16_EN) begin
if (over_sample_cnt_done)
over_sample_cnt <= 4'd15;
else
over_sample_cnt <= over_sample_cnt - 1;
end
end
assign over_sample_cnt_done = (over_sample_cnt == 4'd0);
endmodule
3. 테스트벤치를 위한 my_uart_rx_cntl_tb.v Simulation Sources 생성
4. 테스트벤치 코드 작성
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2024/05/20 13:37:45
// Design Name:
// Module Name: my_uart_rx_cntl_tb
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module my_uart_rx_cntl_tb();
parameter clk_pd = 8.0;
parameter clk_flq = 125_000_000;
parameter baud_rate = 9600;
parameter bit_pd = clk_flq / baud_rate;
reg rst, clk, DATA_rx;
reg oversample_done, bit_cnt_done;
wire [1:0] fsm_state;
my_uart_rx_cntl uut0(
.clk (clk),
.rst (rst),
.DATA_rx (DATA_rx),
.oversample_done (oversample_done),
.bit_cnt_done (bit_cnt_done),
.fsm_state (fsm_state)
);
initial begin
rst = 1'b0;
#(clk_pd*10);
rst = 1'b0;
end
initial clk = 1'b0;
always #(clk_pd/2) clk = ~clk;
initial begin
DATA_rx = 1'b1;
oversample_done = 1'b0;
bit_cnt_done = 1'b0;
wait (!rst);
repeat (10)@ (posedge clk)
DATA_rx = 1'b0;
#(bit_pd/2);
oversample_done = 1'b1;
@(posedge clk)
oversample_done = 1'b1;
bit_cnt_done = 1'b1;
DATA_rx = 1'b1;
@(posedge clk)
oversample_done = 1'b0;
bit_cnt_done = 1'b0;
#(bit_pd/2);
oversample_done = 1'b1;
@(posedge clk)
oversample_done = 1'b0;
$finish;
end
endmodule
5. uart_rx.v Design Sources 생성
6. 코드 작성
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2024/05/20 12:31:27
// Design Name:
// Module Name: uart_rx
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module uart_rx(
input RST,
input CLK,
input RXD,
input PARITY,
input bit_cnt_done,
output [7:0] RX_DATA,
output [1:0] fsm_state
);
wire baud_x16_en;
uart_baud_gen uart_baud_gen (
.RST (RST),
.CLK (CLK),
.BAUD_X16_EN (baud_x16_en)
);
uart_rx_cntl uart_rx_cntl (
.RST (RST),
.CLK (CLK),
.RXD (RXD),
.BAUD_X16_EN (baud_x16_en),
.bit_cnt_done (bit_cnt_done),
.fsm_state (fsm_state)
);
endmodule
7. uart_rx.v의 시뮬레이션을 위한 uart_rx_tb.v Simulation Sources 생성
8. 코드 작성
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2024/05/20 14:09:58
// Design Name:
// Module Name: uart_rx_tb
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module uart_rx_tb();
parameter CLK_PD = 8.0;
reg rst, clk, rxd;
reg bit_cnt_done;
wire [7:0] rx_data;
wire [1:0] fsm_state;
uart_rx uut(
.RST (rst),
.CLK (clk),
.RXD (rxd),
.PARITY (1'b0),
.bit_cnt_done (bit_cnt_done),
.RX_DATA (rx_data),
.fsm_state (fsm_state)
);
initial begin
rst = 1'b1;
#(CLK_PD*10);
rst = 1'b0;
end
initial clk = 1'b0;
always #(CLK_PD/2) clk = ~clk;
initial begin
rxd = 1'b1;
bit_cnt_done = 1'b0;
wait (!rst);
#(CLK_PD * 5);
rxd = 1'b0;
wait (fsm_state == 2'b10);
#(CLK_PD*10);
rxd = 1'b1;
bit_cnt_done = 1'b1;
wait (fsm_state == 2'b00);
#1000;
$finish;
end
endmodule
9. uart_rx_tb.v 파일을 top으로 변경

10. Run Behavioral Simulation

11. uart_rx_cntl.v 코드 수정
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2024/05/20 12:06:26
// Design Name:
// Module Name: uart_rx_cntl
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module uart_rx_cntl(
input RST,
input CLK,
input RXD,
input BAUD_X16_EN,
input bit_cnt_done,
output reg [1:0] fsm_state
);
localparam [1:0] idle = 2'b00,
start= 2'b01,
data = 2'b10,
stop = 2'b11;
reg [1:0] curr_state, next_state;
wire over_sample_cnt_done;
reg [3:0] over_sample_cnt;
reg [3:0] bit_cnt;
wire bit_cnt_done;
always @(posedge CLK)
begin
if(RST)
curr_state <= idle;
else
curr_state <= next_state;
end
always @(curr_state, over_sample_cnt_done, bit_cnt_done, RXD)
begin
case (curr_state)
idle : begin
if(RXD == 1'b0)
next_state = start;
else
next_state = idle;
fsm_state = 2'b00;
end
start : begin
if(over_sample_cnt_done) begin
if(RXD)
next_state = idle;
else
next_state = data;
end
fsm_state = 2'b01;
end
data : begin
if(over_sample_cnt_done && bit_cnt_done)
next_state = stop;
else
next_state = data;
fsm_state = 2'b10;
end
stop : begin
if(over_sample_cnt_done)
next_state = idle;
else
next_state= stop;
fsm_state = 2'b11;
end
default : next_state = idle;
endcase
end
//over sample count
always @(posedge CLK)
begin
if(RST || curr_state == idle)
over_sample_cnt <= 4'd7;
else if(BAUD_X16_EN) begin
if (over_sample_cnt_done)
over_sample_cnt <= 4'd15;
else
over_sample_cnt <= over_sample_cnt - 1;
end
end
assign over_sample_cnt_done = (over_sample_cnt == 4'd0);
//bit cnt generate
always @(posedge CLK)
begin
if(RST || curr_state != data)
bit_cnt <= 4'd0;
else if(over_sample_cnt_done)
bit_cnt <= bit_cnt + 1;
end
assign bit_cnt_done = (over_sample_cnt_done && (bit_cnt == 4'd8));
endmodule
12. uart_rx_tb.v 코드 수정
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2024/05/20 14:09:58
// Design Name:
// Module Name: uart_rx_tb
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module uart_rx_tb();
parameter CLK_PD = 8.0;
reg rst, clk, rxd;
//reg bit_cnt_done;
wire [7:0] rx_data;
wire [1:0] fsm_state;
uart_rx uut(
.RST (rst),
.CLK (clk),
.RXD (rxd),
.PARITY (1'b0),
// .bit_cnt_done (bit_cnt_done),
.RX_DATA (rx_data),
.fsm_state (fsm_state)
);
initial begin
rst = 1'b1;
#(CLK_PD*10);
rst = 1'b0;
end
initial clk = 1'b0;
always #(CLK_PD/2) clk = ~clk;
initial begin
rxd = 1'b1;
// bit_cnt_done = 1'b0;
wait (!rst);
#(CLK_PD * 5);
rxd = 1'b0;
wait (fsm_state == 2'b10);
#(CLK_PD*30);
rxd = 1'b1;
// bit_cnt_done = 1'b1;
wait (fsm_state == 2'b00);
#1000;
$finish;
end
endmodule
13. Run Behavioral Simulation

시뮬레이션