
Device Under Test
1 //-----------------------------------------------------
2 // Design Name : uart
3 // File Name : uart.v
4 // Function : Simple UART
5 // Coder : Deepak Kumar Tala
6 //-----------------------------------------------------
7 module uart (
8 reset ,
9 txclk ,
10 ld_tx_data ,
11 tx_data ,
12 tx_enable ,
13 tx_out ,
14 tx_empty ,
15 rxclk ,
16 uld_rx_data ,
17 rx_data ,
18 rx_enable ,
19 rx_in ,
20 rx_empty
21 );
22 // Port declarations
23 input reset ;
24 input txclk ;
25 input ld_tx_data ;
26 input [7:0] tx_data ;
27 input tx_enable ;
28 output tx_out ;
29 output tx_empty ;
30 input rxclk ;
31 input uld_rx_data ;
32 output [7:0] rx_data ;
33 input rx_enable ;
34 input rx_in ;
35 output rx_empty ;
36
37 // Internal Variables
38 reg [7:0] tx_reg ;
39 reg tx_empty ;
40 reg tx_over_run ;
41 reg [3:0] tx_cnt ;
42 reg tx_out ;
43 reg [7:0] rx_reg ;
44 reg [7:0] rx_data ;
45 reg [3:0] rx_sample_cnt ;
46 reg [3:0] rx_cnt ;
47 reg rx_frame_err ;
48 reg rx_over_run ;
49 reg rx_empty ;
50 reg rx_d1 ;
51 reg rx_d2 ;
52 reg rx_busy ;
53
54 // UART RX Logic
55 always @ (posedge rxclk or posedge reset)
56 if (reset) begin
57 rx_reg <= 0;
58 rx_data <= 0;
59 rx_sample_cnt <= 0;
60 rx_cnt <= 0;
61 rx_frame_err <= 0;
62 rx_over_run <= 0;
63 rx_empty <= 1;
64 rx_d1 <= 1;
65 rx_d2 <= 1;
66 rx_busy <= 0;
67 end else begin
68 // Synchronize the asynch signal
69 rx_d1 <= rx_in;
70 rx_d2 <= rx_d1;
71 // Uload the rx data
72 if (uld_rx_data) begin
73 rx_data <= rx_reg;
74 rx_empty <= 1;
75 end
76 // Receive data only when rx is enabled
77 if (rx_enable) begin
78 // Check if just received start of frame
79 if ( ! rx_busy && ! rx_d2) begin
80 rx_busy <= 1;
81 rx_sample_cnt <= 1;
82 rx_cnt <= 0;
83 end
84 // Start of frame detected, Proceed with rest of data
85 if (rx_busy) begin
86 rx_sample_cnt <= rx_sample_cnt + 1;
87 // Logic to sample at middle of data
88 if (rx_sample_cnt == 7) begin
89 if ((rx_d2 == 1) && (rx_cnt == 0)) begin
90 rx_busy <= 0;
91 end else begin
92 rx_cnt <= rx_cnt + 1;
93 // Start storing the rx data
94 if (rx_cnt > 0 && rx_cnt < 9) begin
95 rx_reg[rx_cnt - 1] <= rx_d2;
96 end
97 if (rx_cnt == 9) begin
98 rx_busy <= 0;
99 // Check if End of frame received correctly
100 if (rx_d2 == 0) begin
101 rx_frame_err <= 1;
102 end else begin
103 rx_empty <= 0;
104 rx_frame_err <= 0;
105 // Check if last rx data was not unloaded,
106 rx_over_run <= (rx_empty) ? 0 : 1;
107 end
108 end
109 end
110 end
111 end
112 end
113 if ( ! rx_enable) begin
114 rx_busy <= 0;
115 end
116 end
117
118 // UART TX Logic
119 always @ (posedge txclk or posedge reset)
120 if (reset) begin
121 tx_reg <= 0;
122 tx_empty <= 1;
123 tx_over_run <= 0;
124 tx_out <= 1;
125 tx_cnt <= 0;
126 end else begin
127 if (ld_tx_data) begin
128 if ( ! tx_empty) begin
129 tx_over_run <= 0;
130 end else begin
131 tx_reg <= tx_data;
132 tx_empty <= 0;
133 end
134 end
135 if (tx_enable && ! tx_empty) begin
136 tx_cnt <= tx_cnt + 1;
137 if (tx_cnt == 0) begin
138 tx_out <= 0;
139 end
140 if (tx_cnt > 0 && tx_cnt < 9) begin
141 tx_out <= tx_reg[tx_cnt -1];
142 end
143 if (tx_cnt == 9) begin
144 tx_out <= 1;
145 tx_cnt <= 0;
146 tx_empty <= 1;
147 end
148 end
149 if ( ! tx_enable) begin
150 tx_cnt <= 0;
151 end
152 end
153
154 endmodule
HDL Testbench Top
1 `include "uart.v"
2 module top();
3
4 reg reset ;
5 reg txclk ;
6 reg ld_tx_data ;
7 reg [7:0] tx_data ;
8 reg tx_enable ;
9 wire tx_out ;
10 wire tx_empty ;
11 reg rxclk ;
12 reg uld_rx_data ;
13 wire [7:0] rx_data ;
14 reg rx_enable ;
15 wire rx_in ;
16 wire rx_empty ;
17 reg loopback ;
18 reg rx_tb_in ;
19
20 initial begin
21 reset = 0;
22 txclk = 0;
23 ld_tx_data = 0;
24 tx_data = 0;
25 tx_enable = 0;
26 rxclk = 0;
27 uld_rx_data = 0;
28 rx_enable = 0;
29 loopback = 0;
30 rx_tb_in = 1;
31 end
32 // Loopback control logic
33 assign rx_in = (loopback) ? tx_out : rx_tb_in;
34 // RX and TX Clock generation
35 always #1 rxclk = ~rxclk;
36 always #16 txclk = ~txclk;
37
38 // DUT Connected here
39 uart U (
40 .reset (reset),
41 .txclk (txclk),
42 .ld_tx_data (ld_tx_data),
43 .tx_data (tx_data),
44 .tx_enable (tx_enable),
45 .tx_out (tx_out),
46 .tx_empty (tx_empty),
47 .rxclk (rxclk),
48 .uld_rx_data (uld_rx_data),
49 .rx_data (rx_data),
50 .rx_enable (rx_enable),
51 .rx_in (rx_in),
52 .rx_empty (rx_empty)
53 );
54
55 endmodule
E Testbench Top
1 <'
2 import uart_clk.e;
3 import uart_sb.e;
4 import uart_txgen.e;
5
6 struct uart_tb {
7
8 sb : uart_sb;
9 txgen : uart_txgen;
10 keep txgen.sb == sb;
11
12 go()@sys.any is {
13 start txgen.goTxgen();
14 start terminate();
15 };
16
17 terminate()@sys.txclk is {
18 var timeout : uint = 0;
19 while ( ! txgen.isDone()) {
20 wait cycle;
21 };
22 wait [20]*cycle;
23 outf("%dns : Termintating the simulation\n",sys.time);
24 stop_run();
25 };
26 };
27
28 extend sys {
29 tb : uart_tb;
30 run() is also {
31 start tb.go();
32 };
33 };
34 '>
UART Clock
1 <'
2 extend sys {
3 event rxclk is rise('top.rxclk') @sim;
4 event txclk is rise('top.txclk') @sim;
5 };
6 '>
Bạn Có Đam Mê Với Vi Mạch hay Nhúng - Bạn Muốn Trau Dồi Thêm Kĩ Năng
Mong Muốn Có Thêm Cơ Hội Trong Công Việc
Và Trở Thành Một Người Có Giá Trị Hơn
Mong Muốn Có Thêm Cơ Hội Trong Công Việc
Và Trở Thành Một Người Có Giá Trị Hơn