Merge pull request #1073 from whitequark/ecp5-diamond-iob
[yosys.git] / tests / asicworld / code_hdl_models_uart.v
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