如何通过UART读取文本文件?

时间:2017-05-04 03:09:10

标签: matrix vhdl fpga

我有一个用于UART组件的VHDL模块,用于在FPGA和PC之间发送和接收串行数据。它目前工作正常。但是,我如何使用这种串行通信来解释从PC发送到FPGA的文本文件中的2-d整数矩阵? 更具体地说,一旦文本文件从PC发送到fpga,2-d数组将如何存储在内存中?我不知道如何在vhdl中执行此操作

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity uart is
   generic(
     -- Default setting:
     -- 19,200 baud, 8 data bis, 1 stop its, 2^2 FIFO
     DBIT: integer:=8;     -- # data bits
      SB_TICK: integer:=16; -- # ticks for stop bits, 16/24/32
                            --   for 1/1.5/2 stop bits
      DVSR: integer:= 326;  -- baud rate divisor
                            -- DVSR = 100M/(16*baud rate)
      DVSR_BIT: integer:=9; -- # bits of DVSR
      FIFO_W: integer:=2    -- # addr bits of FIFO
                            -- # words in FIFO=2^FIFO_W
   );
   port(
      clk, reset: in std_logic;
      rd_uart, wr_uart: in std_logic;
      rx: in std_logic;
      w_data: in std_logic_vector(7 downto 0);
      tx_full, rx_empty: out std_logic;
      r_data: out std_logic_vector(7 downto 0);
      tx: out std_logic
   );
end uart;

architecture str_arch of uart is
   signal tick: std_logic;
   signal rx_done_tick: std_logic;
   signal tx_fifo_out: std_logic_vector(7 downto 0);
   signal rx_data_out: std_logic_vector(7 downto 0);
   signal tx_empty, tx_fifo_not_empty: std_logic;
   signal tx_done_tick: std_logic;
begin
   baud_gen_unit: entity work.mod_m_counter(arch)
      generic map(M=>DVSR, N=>DVSR_BIT)
      port map(clk=>clk, reset=>reset,
               q=>open, max_tick=>tick);
   uart_rx_unit: entity work.uart_rx(arch)
      generic map(DBIT=>DBIT, SB_TICK=>SB_TICK)
      port map(clk=>clk, reset=>reset, rx=>rx,
               s_tick=>tick, rx_done_tick=>rx_done_tick,
               dout=>rx_data_out);
   fifo_rx_unit: entity work.fifo(arch)
      generic map(B=>DBIT, W=>FIFO_W)
      port map(clk=>clk, reset=>reset, rd=>rd_uart,
               wr=>rx_done_tick, w_data=>rx_data_out,
               empty=>rx_empty, full=>open, r_data=>r_data);
   fifo_tx_unit: entity work.fifo(arch)
      generic map(B=>DBIT, W=>FIFO_W)
      port map(clk=>clk, reset=>reset, rd=>tx_done_tick,
               wr=>wr_uart, w_data=>w_data, empty=>tx_empty,
               full=>tx_full, r_data=>tx_fifo_out);
   uart_tx_unit: entity work.uart_tx(arch)
      generic map(DBIT=>DBIT, SB_TICK=>SB_TICK)
      port map(clk=>clk, reset=>reset,
               tx_start=>tx_fifo_not_empty,
               s_tick=>tick, din=>tx_fifo_out,
               tx_done_tick=> tx_done_tick, tx=>tx);
   tx_fifo_not_empty <= not tx_empty;
end str_arch;

1 个答案:

答案 0 :(得分:1)

UART只是一种通信协议,因此它对接收数据的含义完全无能为力。您可以做的是动态解释数据而不是稍后执行此操作,但我仍然建议您在单独的模块中执行此操作。

最简单的方法(如果适用)是先了解矩阵大小和/或以各种方式移动问题软件方。

您可以通过硬连线设计中的已知尺寸(例如N-by-4矩阵格式,hardwire 4列)来简化操作,但最通用的做法是让PC为您完成工作(如果没有)尺寸是先验已知的,你不能根据条目的数量计算出尺寸。)

你可以,例如,指示PC发送这样的东西 NumberRows NumberColumns Value[0][0] Value[0][1] . . Value[NumberRows-1][NumberColumns-1]

现在,您可以将收到的所有内容保存在内存中,并且知道在哪里查看行数和列数,然后从那里开始。

如果您不能让PC发送除纯文本文件以外的任何内容,您将拥有一个必须在本地解析的ASCII字符流。我的建议是设计一个模块,存储除分隔符之外的任何内容,并在检测到分隔符时开始从缓冲区中的ASCII十进制到二进制的转换,然后将其保存在内存中。在分隔符时,它还应该递增一个计数器,以便当换行符到达时你知道列的数量,而在换行符时它应该递增另一个计数器,以便在EOF上你知道行数。