參考資訊:
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
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)
