2014年2月27日木曜日

AVNET LX9 MicroBoardでUART出力

はじめに

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
パリティ:なし
フロー制御:なし

enter image description here

できた!

0 件のコメント:

コメントを投稿