From a864ca3d7e3435e8193cb9a3714888d6d980ebce Mon Sep 17 00:00:00 2001 From: Paul Mathieu Date: Sat, 17 Apr 2021 23:09:30 -0700 Subject: [PATCH] dsp: allow fetching instructions from SRAM --- dsp/dsp.vhdl | 108 +++++++++++++++++++++++++++++----------------- dsp/dsp_test.vhdl | 39 ++++++++++++++--- dsp/makefile | 5 +-- dsp/ram.vhdl | 57 ++++++++++++++++++++++++ 4 files changed, 159 insertions(+), 50 deletions(-) create mode 100644 dsp/ram.vhdl diff --git a/dsp/dsp.vhdl b/dsp/dsp.vhdl index c6693cb..fa9e2f2 100644 --- a/dsp/dsp.vhdl +++ b/dsp/dsp.vhdl @@ -42,15 +42,20 @@ architecture rtl of dsp is ( addressWidth : in positive := 16; busWidth : in positive := 16; - size : in positive := 1024 + size : in positive := 4096 ); port ( clk : in std_logic; - address : in std_logic_vector(addressWidth - 1 downto 0); - writeEnable : in std_logic; - dataIn : in std_logic_vector(busWidth - 1 downto 0); - dataOut : out std_logic_vector(busWidth - 1 downto 0) + -- port A + addra : in std_logic_vector(addressWidth - 1 downto 0); + wea : in std_logic; + dina : in std_logic_vector(busWidth - 1 downto 0); + douta : out std_logic_vector(busWidth - 1 downto 0); + + -- port B (read only) + addrb : in std_logic_vector(addressWidth - 1 downto 0); + doutb : out std_logic_vector(busWidth - 1 downto 0) ); end component; @@ -151,8 +156,10 @@ architecture rtl of dsp is ); end component; - signal mem_write : std_logic; - signal rom_code_addr, rom_code_out, mem_in, mem_out, mem_addr: std_logic_vector(15 downto 0); + signal mem_wea : std_logic; + signal rom_code_addr, rom_code_out: std_logic_vector(15 downto 0); + signal mem_dina, mem_douta, mem_addra: std_logic_vector(15 downto 0); + signal mem_doutb, mem_addrb: std_logic_vector(15 downto 0); signal rom_data_addr, rom_data_out: std_logic_vector(15 downto 0); signal uart_din, uart_dout, uart_addr: std_logic_vector(15 downto 0); @@ -169,22 +176,25 @@ architecture rtl of dsp is signal pdmout0_din, pdmout0_addr: std_logic_vector(15 downto 0); signal pdmout0_we : std_logic; - signal bus_write, bus_read: std_logic; - signal bus_mosi, bus_miso, bus_addr: std_logic_vector(15 downto 0); + signal dbus_write, dbus_read: std_logic; + signal dbus_mosi, dbus_miso, dbus_addr: std_logic_vector(15 downto 0); + + signal ibus_miso, ibus_addr: std_logic_vector(15 downto 0); signal led_r, led_next: std_logic_vector(7 downto 0); begin cpu0: cpu port map(clk => clk, rst => rst, - code_data => rom_code_out, code_addr => rom_code_addr, + code_data => ibus_miso, code_addr => ibus_addr, mem_in => cpu_miso, mem_out => cpu_mosi, mem_addr => cpu_addr, mem_write => cpu_write, mem_read => cpu_read, mem_busy => cpu_busy); rom: boot_rom port map(clk => clk, code_addr => rom_code_addr, code_out => rom_code_out, data_addr => rom_data_addr, data_out => rom_data_out); - mem: ram port map(clk => clk, address => mem_addr, writeEnable => mem_write, - dataIn => mem_in, dataOut => mem_out); + mem: ram port map(clk => clk, + addra => mem_addra, wea => mem_wea, dina => mem_dina, douta => mem_douta, + addrb => mem_addrb, doutb => mem_doutb); uart0: uart port map(clk => clk, rst => rst, rx_pin => uart_rx, tx_pin => uart_tx, addr => uart_addr, din => uart_din, dout => uart_dout, @@ -207,8 +217,8 @@ begin m1_addr => square_addr, m1_wdata => square_mosi, m1_rdata => open, m1_re => '0', m1_we => square_write, m1_busy => square_busy, - bus_addr => bus_addr, bus_wdata => bus_mosi, bus_rdata => bus_miso, - bus_re => bus_read, bus_we => bus_write + bus_addr => dbus_addr, bus_wdata => dbus_mosi, bus_rdata => dbus_miso, + bus_re => dbus_read, bus_we => dbus_write ); -- system map @@ -221,6 +231,23 @@ begin led <= led_r; + -- IBUS interconnect + mem_addrb <= x"0" & ibus_addr(11 downto 0); + rom_code_addr <= x"0" & ibus_addr(11 downto 0); + + process(ibus_addr, rom_code_out, mem_doutb) + begin + case ibus_addr(15 downto 12) is + when x"0" => + ibus_miso <= rom_code_out; + when x"1" => + ibus_miso <= mem_doutb; + when others => + ibus_miso <= x"0000"; + end case; + end process; + + -- LED process(clk, rst) begin if rising_edge(clk) then @@ -232,52 +259,53 @@ begin end if; end process; - process(bus_addr, bus_mosi, bus_write, mem_out, rst, rom_data_out, led_r, bus_read, uart_dout) + -- DBUS interconnect + mem_addra <= x"0" & dbus_addr(11 downto 0); + rom_data_addr <= x"0" & dbus_addr(11 downto 0); + + uart_addr <= x"000" & dbus_addr(3 downto 0); + pdmout0_addr <= x"000" & dbus_addr(3 downto 0); + square0_s_addr <= x"000" & dbus_addr(3 downto 0); + + process(dbus_addr, dbus_mosi, dbus_write, mem_douta, rst, rom_data_out, led_r, dbus_read, uart_dout) begin + dbus_miso <= x"0000"; - bus_miso <= x"0000"; - - rom_data_addr <= bus_addr and x"0fff"; - - mem_addr <= bus_addr and x"0fff"; - mem_in <= bus_mosi; - mem_write <= '0'; + mem_dina <= dbus_mosi; + mem_wea <= '0'; led_next <= led_r; - uart_din <= bus_mosi; - uart_addr <= bus_addr and x"000f"; + uart_din <= dbus_mosi; uart_we <= '0'; uart_re <= '0'; pdmout0_we <= '0'; - pdmout0_addr <= bus_addr and x"000f"; - pdmout0_din <= bus_mosi; + pdmout0_din <= dbus_mosi; square0_s_we <= '0'; - square0_s_addr <= bus_addr and x"000f"; - square0_s_din <= bus_mosi; + square0_s_din <= dbus_mosi; - case bus_addr(15 downto 12) is + case dbus_addr(15 downto 12) is when x"0" => - bus_miso <= rom_data_out; + dbus_miso <= rom_data_out; when x"1" => - bus_miso <= mem_out; - mem_write <= bus_write; + dbus_miso <= mem_douta; + mem_wea <= dbus_write; when x"c" => - case bus_addr(7 downto 4) is + case dbus_addr(7 downto 4) is when x"0" => -- LED - if bus_write = '1' then - led_next <= bus_mosi(7 downto 0); + if dbus_write = '1' then + led_next <= dbus_mosi(7 downto 0); end if; when x"1" => -- UART0 - bus_miso <= uart_dout; - uart_we <= bus_write; - uart_re <= bus_read; + dbus_miso <= uart_dout; + uart_we <= dbus_write; + uart_re <= dbus_read; when x"2" => -- PDMOUT0 - pdmout0_we <= bus_write; + pdmout0_we <= dbus_write; when x"3" => -- SQUARE0 - square0_s_we <= bus_write; + square0_s_we <= dbus_write; when others => end case; when others => diff --git a/dsp/dsp_test.vhdl b/dsp/dsp_test.vhdl index 6c8bd0e..ce83611 100644 --- a/dsp/dsp_test.vhdl +++ b/dsp/dsp_test.vhdl @@ -34,7 +34,12 @@ architecture rtl of dsp_test is signal pdmout0: std_logic; type str is array(integer range <>) of std_logic_vector(7 downto 0); - signal blarg: str(0 to 4) := (x"61", x"64", x"64", x"61", x"64"); + signal prog: str(0 to 7) := ( + x"63", x"11", x"00", x"04", x"e0", x"00", x"5e", x"00"); + signal jump: str(0 to 2) := ( + x"6a", x"11", x"00"); + + constant UART_PERIOD: time := 1000 ns; begin dut: dsp port map(clk => clk, rst => rst, @@ -56,21 +61,41 @@ begin rst <= '0'; wait for 20 us; - for i in 0 to 4 loop + for i in 0 to 7 loop uart_rx <= '0'; -- start bit - wait for 8681 ns; + wait for UART_PERIOD; for j in 0 to 7 loop - uart_rx <= blarg(i)(j); - wait for 8681 ns; + uart_rx <= prog(i)(j); + wait for UART_PERIOD; end loop; uart_rx <= '1'; -- stop bit - wait for 8681 ns; + wait for UART_PERIOD; end loop; - wait for 2 ms; + wait for 2 us; + + assert(led = x"f0") report "Fail prog" severity error; + + for i in 0 to 2 loop + uart_rx <= '0'; -- start bit + wait for UART_PERIOD; + + for j in 0 to 7 loop + uart_rx <= jump(i)(j); + wait for UART_PERIOD; + end loop; + + uart_rx <= '1'; -- stop bit + wait for UART_PERIOD; + + end loop; + + wait for 2 us; + + assert(led = x"01") report "Fail prog" severity error; assert false report "Test done." severity note; diff --git a/dsp/makefile b/dsp/makefile index da9c20d..2261c0c 100644 --- a/dsp/makefile +++ b/dsp/makefile @@ -11,12 +11,11 @@ CFLAGS = -I../wave -I../uart boot_rom.gen.vhdl: main.o ../uart/uart.o sim_sources = dsp_test.vhdl -sources = boot_rom.gen.vhdl dsp.vhdl \ +sources = boot_rom.gen.vhdl dsp.vhdl ram.vhdl \ ../cpu/cpu.vhdl ../cpu/reg.vhdl ../cpu/alu.vhdl \ $(wildcard ../wave/*.vhdl) \ $(wildcard ../sysbus/*.vhdl) \ - ../uart/uart.vhdl \ - ../first/ram.vhdl + ../uart/uart.vhdl ../lab/dsp/au_base_project.runs/impl_1/au_top.bin: ../lab/dsp/au_base_project.runs/synth_1/au_top.dcp ../lab/dsp/au_base_project.runs/impl_1/runme.sh diff --git a/dsp/ram.vhdl b/dsp/ram.vhdl new file mode 100644 index 0000000..23d7e0e --- /dev/null +++ b/dsp/ram.vhdl @@ -0,0 +1,57 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +-- Aligned IO only. +-- Unaligned addra bits are ignored. +-- E.g. on a 16-bit bus, last addra bit is ignored. +entity ram is + generic + ( + addressWidth : in positive := 16; + busWidth : in positive := 16; + size : in positive := 1024 + ); + port + ( + clk : in std_logic; + + -- port A + addra : in std_logic_vector(addressWidth - 1 downto 0); + wea : in std_logic; + dina : in std_logic_vector(busWidth - 1 downto 0); + douta : out std_logic_vector(busWidth - 1 downto 0); + + -- port B (read only) + addrb : in std_logic_vector(addressWidth - 1 downto 0); + doutb : out std_logic_vector(busWidth - 1 downto 0) + ); +end ram; + +architecture Behavioral of ram is + constant alignment : positive := busWidth / 8; + constant ramSize : positive := size / alignment; + + type ramType is array(natural range <>) of std_logic_vector(busWidth - 1 downto 0); + subtype ramRange is natural range 0 to ramSize; + + signal mem : ramType(ramRange); +begin + process(clk) + variable indexa, indexb : ramRange; + begin + if (rising_edge(clk)) + then + indexa := to_integer(unsigned(addra)) / alignment; + indexb := to_integer(unsigned(addrb)) / alignment; + + if (wea = '1') + then + mem(indexa) <= dina; + end if; + + douta <= mem(indexa); + doutb <= mem(indexb); + end if; + end process; +end Behavioral;