bring bram signals out to top_level, initially for debugging purposes
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 30 Dec 2021 21:25:53 +0000 (21:25 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 30 Dec 2021 21:25:53 +0000 (21:25 +0000)
and ultimately with the purpose of replacing compiled-in verilator hex
dumps with reading/writing a file directly in the main verilator loop

Signed-off-by: Luke Kenneth Casson Leighton <lkcl@lkcl.net>
Makefile
fpga/top-generic.vhdl
soc.vhdl
verilator/microwatt-verilator.cpp
wishbone_bram_wrapper.vhdl

index 678bbfa6ce80ad9ab85d75c6471309b934351bf1..6bc4294731821dfb3fa869d89be9c7edb6349d07 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -144,6 +144,11 @@ RAM_INIT_FILE=hello_world/hello_world.hex
 #MEMORY_SIZE=393216
 #RAM_INIT_FILE=micropython/firmware.hex
 
+# Linux
+#MEMORY_SIZE=16777216 # 268435456
+#RAM_INIT_FILE=dtbImage.microwatt.hex
+SIM_MAIN_BRAM=true
+
 FPGA_TARGET ?= ORANGE-CRAB
 
 # OrangeCrab with ECP85
@@ -171,7 +176,9 @@ OPENOCD_DEVICE_CONFIG=openocd/LFE5UM5G-85F.cfg
 endif
 
 GHDL_IMAGE_GENERICS=-gMEMORY_SIZE=$(MEMORY_SIZE) -gRAM_INIT_FILE=$(RAM_INIT_FILE) \
-       -gRESET_LOW=$(RESET_LOW) -gCLK_INPUT=$(CLK_INPUT) -gCLK_FREQUENCY=$(CLK_FREQUENCY)
+       -gRESET_LOW=$(RESET_LOW) -gCLK_INPUT=$(CLK_INPUT) -gCLK_FREQUENCY=$(CLK_FREQUENCY) \
+       -gSIM_MAIN_BRAM=$(SIM_MAIN_BRAM)
+
 
 clkgen=fpga/clk_gen_ecp5.vhd
 toplevel=fpga/top-generic.vhdl
@@ -184,8 +191,11 @@ CLK_FREQUENCY=50000000
 clkgen=fpga/clk_gen_bypass.vhd
 endif
 
+FPGA_MAIN_BRAM=fpga/main_bram.vhdl
+#FPGA_MAIN_BRAM=
+
 fpga_files = $(core_files) $(soc_files) fpga/soc_reset.vhdl \
-       fpga/pp_fifo.vhd fpga/pp_soc_uart.vhd fpga/main_bram.vhdl \
+       fpga/pp_fifo.vhd fpga/pp_soc_uart.vhd $(FPGA_MAIN_BRAM) \
        nonrandom.vhdl
 
 synth_files = $(core_files) $(soc_files) $(fpga_files) $(clkgen) $(toplevel) $(dmi_dtm)
@@ -198,7 +208,7 @@ microwatt.v: $(synth_files) $(RAM_INIT_FILE)
 
 # Need to investigate why yosys is hitting verilator warnings, and eventually turn on -Wall
 microwatt-verilator: microwatt.v verilator/microwatt-verilator.cpp verilator/uart-verilator.c
-       verilator -O3 -CFLAGS "-DCLK_FREQUENCY=$(CLK_FREQUENCY)" --assert --cc microwatt.v --exe verilator/microwatt-verilator.cpp verilator/uart-verilator.c -o $@ -Iuart16550 -Wno-fatal -Wno-CASEOVERLAP -Wno-UNOPTFLAT #--trace
+       verilator -O3 -CFLAGS "-DCLK_FREQUENCY=$(CLK_FREQUENCY)" --assert --cc microwatt.v --exe verilator/microwatt-verilator.cpp verilator/uart-verilator.c -o $@ -Iuart16550 -Wno-fatal -Wno-CASEOVERLAP -Wno-UNOPTFLAT --trace
        make -C obj_dir -f Vmicrowatt.mk
        @cp -f obj_dir/microwatt-verilator microwatt-verilator
 
index 8bff5bb6fa5362cc78480a543e151b929ae7848e..6cec9fef243381a797fd2fc45b0f382a1ac2bacf 100644 (file)
@@ -3,12 +3,14 @@ use ieee.std_logic_1164.all;
 
 library work;
 use work.wishbone_types.all;
+use work.utils.all;
 
 entity toplevel is
     generic (
        MEMORY_SIZE   : positive := (384*1024);
        RAM_INIT_FILE : string   := "firmware.hex";
        RESET_LOW     : boolean  := true;
+       SIM_MAIN_BRAM     : boolean  := false;
        CLK_INPUT     : positive := 100000000;
        CLK_FREQUENCY : positive := 100000000;
         HAS_FPU       : boolean  := true;
@@ -23,7 +25,15 @@ entity toplevel is
 
        -- UART0 signals:
        uart0_txd : out std_ulogic;
-       uart0_rxd : in  std_ulogic
+       uart0_rxd : in  std_ulogic;
+
+    -- BRAM verilator access
+       bram_we : out std_ulogic;
+       bram_re : out std_ulogic;
+    bram_addr : out std_logic_vector(log2ceil(MEMORY_SIZE) - 3- 1 downto 0);
+    bram_di   : inout std_logic_vector(63 downto 0);
+    bram_do   : out std_logic_vector(63 downto 0);
+    bram_sel  : out std_logic_vector(7 downto 0)
        );
 end entity toplevel;
 
@@ -68,6 +78,7 @@ begin
     soc0: entity work.soc
        generic map(
            MEMORY_SIZE   => MEMORY_SIZE,
+           SIM_MAIN_BRAM   => SIM_MAIN_BRAM,
            RAM_INIT_FILE => RAM_INIT_FILE,
            SIM           => false,
            CLK_FREQ      => CLK_FREQUENCY,
@@ -81,7 +92,13 @@ begin
            system_clk        => system_clk,
            rst               => soc_rst,
            uart0_txd         => uart0_txd,
-           uart0_rxd         => uart0_rxd
+           uart0_rxd         => uart0_rxd,
+        bram_we           => bram_we,
+        bram_re           => bram_re,
+        bram_addr           => bram_addr,
+        bram_di             => bram_di,
+        bram_do             => bram_do,
+        bram_sel            => bram_sel
            );
 
 end architecture behaviour;
index 77f229e6dd7d6eb317caeb7bb0bdb6fa51caf584..73d6292817986a1a46992b9fb9bd6d09e3e32945 100644 (file)
--- a/soc.vhdl
+++ b/soc.vhdl
@@ -7,6 +7,7 @@ use std.env.stop;
 
 library work;
 use work.common.all;
+use work.utils.all;
 use work.wishbone_types.all;
 
 
@@ -56,6 +57,7 @@ entity soc is
         HAS_BTC            : boolean := true;
        DISABLE_FLATTEN_CORE : boolean := false;
        HAS_DRAM           : boolean  := false;
+       SIM_MAIN_BRAM      : boolean  := false;
        DRAM_SIZE          : integer := 0;
         DRAM_INIT_SIZE     : integer := 0;
         HAS_SPI_FLASH      : boolean := false;
@@ -86,6 +88,14 @@ entity soc is
         -- External interrupts
         ext_irq_eth          : in std_ulogic := '0';
 
+    -- BRAM verilator access
+    bram_we : out std_ulogic;
+    bram_re : out std_ulogic;
+    bram_addr : out std_logic_vector(log2ceil(MEMORY_SIZE) - 3- 1 downto 0);
+    bram_di   : inout std_logic_vector(63 downto 0);
+    bram_do   : out std_logic_vector(63 downto 0);
+    bram_sel  : out std_logic_vector(7 downto 0);
+
        -- UART0 signals:
        uart0_txd    : out std_ulogic;
        uart0_rxd    : in  std_ulogic := '0';
@@ -825,13 +835,20 @@ begin
         bram0: entity work.wishbone_bram_wrapper
             generic map(
                 MEMORY_SIZE   => MEMORY_SIZE,
-                RAM_INIT_FILE => RAM_INIT_FILE
+                RAM_INIT_FILE => RAM_INIT_FILE,
+                SIM_MAIN_BRAM => SIM_MAIN_BRAM
                 )
             port map(
                 clk => system_clk,
                 rst => rst_bram,
                 wishbone_in => wb_bram_in,
-                wishbone_out => wb_bram_out
+                wishbone_out => wb_bram_out,
+                bram_we           => bram_we,
+                bram_re           => bram_re,
+                bram_addr           => bram_addr,
+                bram_di             => bram_di,
+                bram_do             => bram_do,
+                bram_sel            => bram_sel
                 );
     end generate;
 
index 1e8282082296ebaf6ab94f22a18f60a77f572d1b..89d4ce488c5355f294d34f1df256800341aa1977 100644 (file)
@@ -1,4 +1,5 @@
 #include <stdlib.h>
+#include <stdio.h>
 #include "Vmicrowatt.h"
 #include "verilated.h"
 #include "verilated_vcd_c.h"
@@ -72,6 +73,14 @@ int main(int argc, char **argv)
 
                uart_tx(top->uart0_txd);
                top->uart0_rxd = uart_rx();
+        if (top->bram_we) {
+            printf("bram wr addr %x dout %x sel %x\n",
+                    top->bram_addr, top->bram_di, top->bram_sel);
+        }
+        if (top->bram_re) {
+            printf("bram rd addr %x din %x sel %x\n",
+                    top->bram_addr, top->bram_do, top->bram_sel);
+        }
        }
 
 #if VM_TRACE
index 2cf2a17a28e14140218eee9928c33df4d8314cf0..fe26d588961e1c2aa22ceb5cf15591820d2646ee 100644 (file)
@@ -11,7 +11,8 @@ use work.wishbone_types.all;
 entity wishbone_bram_wrapper is
     generic(
        MEMORY_SIZE   : natural := 4096; --! Memory size in bytes.
-       RAM_INIT_FILE : string
+       RAM_INIT_FILE : string;
+    SIM_MAIN_BRAM : boolean := false
        );
     port(
        clk : in std_logic;
@@ -19,7 +20,16 @@ entity wishbone_bram_wrapper is
 
        -- Wishbone interface:
        wishbone_in  : in wishbone_master_out;
-       wishbone_out : out wishbone_slave_out
+       wishbone_out : out wishbone_slave_out;
+
+    -- BRAM verilator access
+    bram_we : out std_ulogic;
+    bram_re : out std_ulogic;
+    bram_addr : out std_logic_vector(log2ceil(MEMORY_SIZE) - 3- 1 downto 0);
+    bram_di   : inout std_logic_vector(63 downto 0);
+    bram_do   : out std_logic_vector(63 downto 0);
+    bram_sel  : out std_logic_vector(7 downto 0)
+
        );
 end entity wishbone_bram_wrapper;
 
@@ -36,22 +46,32 @@ architecture behaviour of wishbone_bram_wrapper is
 begin
 
     -- Actual RAM template
-    ram_0: entity work.main_bram
-       generic map(
-           WIDTH => 64,
-           HEIGHT_BITS => ram_addr_bits,
-           MEMORY_SIZE => MEMORY_SIZE,
-           RAM_INIT_FILE => RAM_INIT_FILE
-           )
-       port map(
-           clk => clk,
-           addr => ram_addr,
-           di => wishbone_in.dat,
-           do => wishbone_out.dat,
-           sel => wishbone_in.sel,
-           re => ram_re,
-           we => ram_we
-           );
+    sim_ram: if SIM_MAIN_BRAM = true generate
+        ram_0: entity work.main_bram
+        generic map(
+            WIDTH => 64,
+            HEIGHT_BITS => ram_addr_bits,
+            MEMORY_SIZE => MEMORY_SIZE,
+            RAM_INIT_FILE => RAM_INIT_FILE
+            )
+        port map(
+            clk => clk,
+            addr => ram_addr,
+            di => wishbone_in.dat,
+            do => wishbone_out.dat,
+            sel => wishbone_in.sel,
+            re => ram_re,
+            we => ram_we
+            );
+    end generate;
+
+    -- Verilator access to bram signals
+    bram_sel <= wishbone_in.sel;
+    bram_do <= wishbone_out.dat;
+    bram_di <= wishbone_in.dat;
+    bram_addr <= ram_addr;
+    bram_we <= ram_we;
+    bram_re <= ram_re;
 
     -- Wishbone interface
     ram_addr <= wishbone_in.adr(ram_addr_bits + 2 downto 3);