From 2c5ebf4f9f199ec639ef7e677b6fc8cb42868106 Mon Sep 17 00:00:00 2001
From: Tristan Gingold <tristan.gingold@cern.ch>
Date: Mon, 29 Nov 2021 14:41:08 +0100
Subject: [PATCH] Add testbench for sf2-test

---
 hdl/tb/sf2-test/Manifest.py |  16 +++++
 hdl/tb/sf2-test/uart.vhd    | 122 ++++++++++++++++++++++++++++++++++++
 2 files changed, 138 insertions(+)
 create mode 100644 hdl/tb/sf2-test/Manifest.py
 create mode 100644 hdl/tb/sf2-test/uart.vhd

diff --git a/hdl/tb/sf2-test/Manifest.py b/hdl/tb/sf2-test/Manifest.py
new file mode 100644
index 0000000..e27dabb
--- /dev/null
+++ b/hdl/tb/sf2-test/Manifest.py
@@ -0,0 +1,16 @@
+action = "simulation"
+sim_tool = "ghdl"
+top_module = "sf2_test"
+
+files = ['uart.vhd', 'urv.vhd', '../../top/sf2-test/sf2_test.vhd']
+
+#
+
+modules = {
+    'local': ['../../rtl'],
+    "git": [
+        "git://ohwr.org/project/general-cores.git",
+        "git://ohwr.org/project/urv-core.git",
+    ],
+}
+
diff --git a/hdl/tb/sf2-test/uart.vhd b/hdl/tb/sf2-test/uart.vhd
new file mode 100644
index 0000000..0d2908a
--- /dev/null
+++ b/hdl/tb/sf2-test/uart.vhd
@@ -0,0 +1,122 @@
+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;
-- 
GitLab