Flower
Flower

Reputation: 401

How to read text file throuGH UART?

I have a VHDL module for a UART component which sends and receives serial data between an FPGA and PC. It currently works just fine. But how would I use this serial communication to interpret a 2-d matrix of integers in a text file sent from the PC to the FPGA? More specifically once the text file is sent from the PC to the fpga, how would the 2-d array be stored in memory as such? I am not sure how to do this in 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;

Upvotes: 0

Views: 805

Answers (1)

RookieHere
RookieHere

Reputation: 156

UART is just a communication protocol and as such it is totally clueless about the meaning of the received data. What you can do is interpret the data on the fly instead of doing that later, but I would still advise you do that in a separate module.

The easiest way, if applicable, is knowing a priori the matrix size and/or moving the issue software-side in various flavors.

You can hardwire the known dimensions in your design (e.g. N-by-4 matrix format, hardwire 4 columns) to simplify stuff, but the most generic way of doing things is having the PC doing the work for you (if none of the dimensions is known a priori you cannot work out the size from the number of entries).

You could, e.g., instruct the PC to send something like this NumberRows NumberColumns Value[0][0] Value[0][1] . . Value[NumberRows-1][NumberColumns-1]

Now you can just save everything you receive in memory and you know where to look at the number of rows and columns and proceed from there.

If you cannot make the PC send anything else than the pure text file, you will have a stream of ASCII characters you have to parse locally. My advice would be to design a module that stores anything up to the separator and upon detecting a separator starts the conversion from ASCII decimal to binary of whatever it has in the buffer, then saves it in memory. Upon separator it should also increment a counter so that when a newline arrives you know the number of columns, while on newline it should increment another counter so that on EOF you know the number of rows.

Upvotes: 1

Related Questions