はじめに
AVNET LX9 MicroBoardでUART出力してみました。
flashledのサンプルを改良しています。
UARTのIPはOpenCoresに登録されているDocumented Verilog UARTを使用させてもらっています。(MITライセンス)
コード一式はこちらです。
UART出力するVerilog記述
UART IPをインスタンスしてa-zを出力後にCR+LFを出力するコントローラを接続します。
将来的にはCPUをのっけたいところですが、とりあえずUART出力できればよいので適当なタイミングでトリガをかけます。
Xilinx ISEで下記のように入力。
`timescale 1 ns / 1 ps
module ledflash
(
input wire CLK_66MHZ,
input wire USER_RESET,
input wire USB_RS232_RXD,
output wire USB_RS232_TXD,
output wire [3:0] LED
);
//******************************************************************//
// Create clock. //
//******************************************************************//
wire clk;
wire clknub;
wire clk_enable;
assign clk_enable = ~USER_RESET;
DCM_SP DCM_SP_INST(
.CLKIN(CLK_66MHZ),
.CLKFB(clk),
.RST(1'b0),
.PSEN(1'b0),
.PSINCDEC(1'b0),
.PSCLK(1'b0),
.DSSEN(1'b0),
.CLK0(clknub),
.CLK90(),
.CLK180(),
.CLK270(),
.CLKDV(),
.CLK2X(),
.CLK2X180(),
.CLKFX(),
.CLKFX180(),
.STATUS(),
.LOCKED(),
.PSDONE());
defparam DCM_SP_INST.CLKIN_DIVIDE_BY_2 = "FALSE";
defparam DCM_SP_INST.CLKIN_PERIOD = 15.000;
BUFGCE BG (.O(clk), .CE(1'b1), .I(clknub));
//******************************************************************//
// //
//******************************************************************//
reg [26:0] led_count;
always @(posedge clk or posedge USER_RESET) begin
if (USER_RESET) begin
led_count <= 27'd0;
end else begin
led_count <= led_count + 1'b1;
end
end
assign LED[3:0] = led_count[26:23]; // connects led outputs to counter value
reg r_delay;
wire w_trigger;
always @(posedge clk or posedge USER_RESET) begin
if (USER_RESET) begin
r_delay <= 1'b0;
end else begin
r_delay <= led_count[20];
end
end
assign w_trigger = ~r_delay & led_count[20];
reg [7:0] r_char;
always @(posedge clk or posedge USER_RESET) begin
if (USER_RESET) begin
r_char <= "assss";
end else begin
if (w_trigger) begin
if (r_char == "z") begin
r_char <= "\r";
end else if (r_char == "\r") begin
r_char <= "\n";
end else if (r_char == "\n") begin
r_char <= "a";
end else begin
r_char <= r_char + 1'b1;
end
end
end
end
uart #(
.CLOCK_DIVIDE(1736)
) u_uart(
.clk(clk), // The master clock for this module
.rst(USER_RESET), // Synchronous reset.
.rx(USB_RS232_RXD), // Incoming serial line
.tx(USB_RS232_TXD), // Outgoing serial line
.transmit(w_trigger), // Signal to transmit
.tx_byte(r_char), // Byte to transmit
.received(), // Indicated that a byte has been received.
.rx_byte(), // Byte received
.is_receiving(), // Low when receive line is idle.
.is_transmitting(), // Low when transmit line is idle.
.recv_error() // Indicates error in receiving packet.
);
endmodule
UARTのCLOCK_DIVIDE
パラメータには666666666/(4*9600)
で計算した1736
の値を設定します。
テストベンチを作成し、simで動作確認。USB_RS232_TXD
端子がスタートビットでlow, ストップビットでhighになることを確認します。
制約ファイルは下記のとおりです。
NET "CLK_66MHZ" LOC = "K15" | IOSTANDARD = LVCMOS33;
Net CLK_66MHZ TNM_NET = CLK_66MHZ;
TIMESPEC TS_CLK_66MHZ = PERIOD CLK_66MHZ 15000 ps INPUT_JITTER 1000 ps;
NET USB_RS232_RXD LOC = R7 | IOSTANDARD = LVCMOS33; # "USB_RS232_RXD"
NET USB_RS232_TXD LOC = T7 | IOSTANDARD = LVCMOS33; # "USB_RS232_TXD"
NET LED<0> LOC = P4 | IOSTANDARD = LVCMOS18 | DRIVE = 8 | SLEW = SLOW ;
NET LED<1> LOC = L6 | IOSTANDARD = LVCMOS18 | DRIVE = 8 | SLEW = SLOW ;
NET LED<2> LOC = F5 | IOSTANDARD = LVCMOS18 | DRIVE = 8 | SLEW = SLOW ;
NET LED<3> LOC = C2 | IOSTANDARD = LVCMOS18 | DRIVE = 8 | SLEW = SLOW ;
NET USER_RESET LOC = V4 | IOSTANDARD = LVCMOS33 | PULLDOWN; # "USER_RESET"
CONFIG VCCAUX = "3.3" ;
合成, P&Rしてflashled.bit
ファイルをFPGAにコンフィグレーションします。
PuTTYで受信
手始めにWindowsのPuTTYで受信します。
シリアルポート: COM3(自分の環境の場合)
スピード(baudrate): 9600bps
データ長: 8bit
ストップビット長: 1bit
パリティ:なし
フロー制御:なし
できた!
0 件のコメント:
コメントを投稿