Steward
分享是一種喜悅、更是一種幸福
微處理器 - Lattice LCMXO2-4000HC-4MG132C (STEP-MXO2 V2) - Verilog - UART
參考資訊:
https://ftdichip.com/wp-content/uploads/2024/09/DS_FT232H.pdf
https://wiki.stepfpga.com/uart%E4%B8%B2%E5%8F%A3%E6%A8%A1%E5%9D%97
JTAG腳位
FT232HQ腳位
JTAG腳位需要改成GPIO模式,這樣才可以透過FT232HQ傳輸,不過nextpnr-machxo2目前尚未支援JTAG_PORT設定,因此,需要先透過Lattice Diamond編譯修改JTAG腳位在燒錄到板子
下載Bit Stream時,需要先將JTAGENB接到High(JTAG腳位模式),下載後,再將JTAGENB接到Low(GPIO模式),這樣可以就可以透過FT232HQ傳輸資料
main.v
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 | module uart_bus #( parameter bps_para = 1250 ) ( input clk_in, input rst_in, input rs232_rx, output rs232_tx ); wire bps_en_rx; wire bps_clk_rx; wire [7:0] rx_data; baud #( .bps_para (bps_para) ) baud_rx ( .clk_in (clk_in), .rst_in (rst_in), .bps_en (bps_en_rx), .bps_clk (bps_clk_rx) ); uart_rx uart_rx_uut ( .clk_in (clk_in), .rst_in (rst_in), .bps_en (bps_en_rx), .bps_clk (bps_clk_rx), .rs232_rx (rs232_rx), .rx_data (rx_data) ); wire bps_en_tx; wire bps_clk_tx; baud #( .bps_para (bps_para)) baud_tx ( .clk_in (clk_in), .rst_in (rst_in), .bps_en (bps_en_tx), .bps_clk (bps_clk_tx) ); uart_tx uart_tx_uut ( .clk_in (clk_in), .rst_in (rst_in), .bps_en (bps_en_tx), .bps_clk (bps_clk_tx), .rx_bps_en (bps_en_rx), .tx_data (rx_data), .rs232_tx (rs232_tx) ); endmodule module baud #( parameter bps_para = 1250 ) ( input clk_in, input rst_in, input bps_en, output reg bps_clk ); reg [12:0] cnt; always @ ( posedge clk_in or negedge rst_in) begin if (!rst_in) cnt <= 1'b0; else if ((cnt >= ( bps_para - 1)) || (!bps_en)) cnt <= 1'b0; else cnt <= cnt + 1'b1; end always @ ( posedge clk_in or negedge rst_in) begin if (!rst_in) bps_clk <= 1'b0; else if (cnt == ( bps_para >> 1)) bps_clk <= 1'b1; else bps_clk <= 1'b0; end endmodule module uart_rx ( input clk_in, input rst_in, output reg bps_en, input bps_clk, input rs232_rx, output reg [7:0] rx_data ); reg rs232_rx0; reg rs232_rx1; reg rs232_rx2; always @ ( posedge clk_in or negedge rst_in) begin if (!rst_in) begin rs232_rx0 <= 1'b0; rs232_rx1 <= 1'b0; rs232_rx2 <= 1'b0; end else begin rs232_rx0 <= rs232_rx; rs232_rx1 <= rs232_rx0; rs232_rx2 <= rs232_rx1; end end wire neg_rs232_rx = rs232_rx2 & rs232_rx1 & (~rs232_rx0) & (~rs232_rx); reg [3:0] num; always @ ( posedge clk_in or negedge rst_in) begin if (!rst_in) bps_en <= 1'b0; else if (neg_rs232_rx && (!bps_en)) bps_en <= 1'b1; else if (num == 4'd9) bps_en <= 1'b0; end reg [7:0] rx_data_r; always @ ( posedge clk_in or negedge rst_in) begin if (!rst_in) begin num <= 4'd0; rx_data <= 8'd0; rx_data_r <= 8'd0; end else if (bps_en) begin if (bps_clk) begin num <= (num + 1'b1); if (num <= 4'd8) rx_data_r[num-1] <= rs232_rx; end else if (num == 4'd9) begin num <= 4'd0; rx_data <= rx_data_r; end end end endmodule module uart_tx ( input clk_in, input rst_in, output reg bps_en, input bps_clk, input rx_bps_en, input [7:0] tx_data, output reg rs232_tx ); reg rx_bps_en_r; always @ ( posedge clk_in or negedge rst_in) begin if (!rst_in) rx_bps_en_r <= 1'b0; else rx_bps_en_r <= rx_bps_en; end wire neg_rx_bps_en = rx_bps_en_r & (~rx_bps_en); reg [3:0] num; reg [9:0] tx_data_r; always @ ( posedge clk_in or negedge rst_in) begin if (!rst_in) begin bps_en <= 1'b0; tx_data_r <= 8'd0; end else if (neg_rx_bps_en) begin bps_en <= 1'b1; tx_data_r <= {1 'b1, tx_data, 1' b0}; end else if (num == 4'd10) begin bps_en <= 1'b0; end end always @ ( posedge clk_in or negedge rst_in) begin if (!rst_in) begin num <= 1'b0; rs232_tx <= 1'b1; end else if (bps_en) begin if (bps_clk) begin num <= num + 1'b1; rs232_tx <= tx_data_r[num]; end else if (num >= 4'd10) num <= 4'd0; end end endmodule |
main.lpf
LOCATE COMP "clk_in" SITE "C1"; LOCATE COMP "rst_in" SITE "L14"; LOCATE COMP "rs232_tx" SITE "B4"; LOCATE COMP "rs232_rx" SITE "B6";
連接USB就可以做UART Loopback測試(Baudrate 9600bps)