Skip to content
Snippets Groups Projects
uart.vhd 3.49 KiB
use std.textio.all;

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity uart is
  -- Port list
  port(
    -- Inputs
    DEVRST_N              : in  std_logic;
    FIC_0_AHB_S_HADDR     : in  std_logic_vector(31 downto 0);
    FIC_0_AHB_S_HMASTLOCK : in  std_logic;
    FIC_0_AHB_S_HREADY    : in  std_logic;
    FIC_0_AHB_S_HSEL      : in  std_logic;
    FIC_0_AHB_S_HSIZE     : in  std_logic_vector(1 downto 0);
    FIC_0_AHB_S_HTRANS    : in  std_logic_vector(1 downto 0);
    FIC_0_AHB_S_HWDATA    : in  std_logic_vector(31 downto 0);
    FIC_0_AHB_S_HWRITE    : in  std_logic;
    M3_RESET_N            : in  std_logic;
    MMUART_0_RXD          : in  std_logic;
    XTL                   : in  std_logic;
    -- Outputs
    FIC_0_AHB_S_HRDATA    : out std_logic_vector(31 downto 0);
    FIC_0_AHB_S_HREADYOUT : out std_logic;
    FIC_0_AHB_S_HRESP     : out std_logic;
    LOCK                  : out std_logic;
    MMUART_0_TXD          : out std_logic;
    MSS_RESET_N_M2F       : out std_logic;
    POWER_ON_RESET_N      : out std_logic;
    clk_100               : out std_logic
    );
end uart;

architecture RTL of uart is
  type mem_t is array(natural range <>) of std_logic_vector (31 downto 0);

  procedure read_mem (mem : out mem_t; filename : string)
  is
    FILE f_in  : text;
    variable l : line;
    variable addr : natural;
    variable off : natural;
    variable byte : std_logic_vector (0 to 7);
  begin
    --  Read mem
    file_open(f_in, "../../../sw/sf2-test/main.mem", read_mode);

    addr := 0;
    off := 0;
    while not endfile(f_in) loop
      readline (f_in, l);

      assert l'length = 8;
      for j in 0 to 7 loop
        if l(l'left + j) = '1' then
          byte(j) := '1';
        elsif l(l'left + j) = '0' then
          byte(j) := '0';
        else
          assert false severity error;
        end if;
      end loop;

      mem (addr)(off + 7 downto off) := byte;
      if off = 24 then
        off := 0;
        addr := addr + 1;
      else
        off := off + 8;
      end if;
    end loop;
    file_close(f_in);
  end read_mem;

  signal clk_0, clk : std_logic;
begin
    process
    begin
        clk_0 <= '0';
        wait for 5 ns;
        clk_0 <= '1';
        wait for 5 ns;
    end process;

    clk <= clk_0;
    clk_100 <= clk_0;

    POWER_ON_RESET_N <= '0', '1' after 20 ns;
    MSS_RESET_N_M2F <= '1';
    lock <= '1';
    
    process
      variable mem: mem_t (4095 downto 0);
    begin
      read_mem (mem, "../../../sw/sf2-test/main.mem");

      FIC_0_AHB_S_HREADYOUT <= '1';
      loop
        wait until rising_edge(clk);
        if FIC_0_AHB_S_HTRANS = "10" and FIC_0_AHB_S_HSEL = '1' then
          assert FIC_0_AHB_S_HSIZE = "10";
          if FIC_0_AHB_S_HADDR(31 downto 16) = x"6000" then
            -- eNVM
            assert FIC_0_AHB_S_HWRITE = '0';
            FIC_0_AHB_S_HRDATA <= mem (to_integer (unsigned (FIC_0_AHB_S_HADDR(13 downto 2))));
          elsif FIC_0_AHB_S_HADDR(31 downto 16) = x"4000" then
            --  UART
            if FIC_0_AHB_S_HADDR(15 downto 0) = x"0014" then
              --  LSR: tx is always empty, no rx
              FIC_0_AHB_S_HRDATA <= x"000000" & b"0110_0000";
            elsif FIC_0_AHB_S_HADDR(15 downto 0) = x"0000" then
              --  THR.
              if FIC_0_AHB_S_HWRITE = '1' then
                report "uart tx: " & character'val(to_integer(unsigned (FIC_0_AHB_S_HWDATA(7 downto 0))));
              end if;
            end if;
          end if;
        end if;
      end loop;
    end process;
end RTL;