diff --git a/peripherals/sram/DE2_115.vhdl b/peripherals/sram/DE2_115.vhdl new file mode 100644 index 00000000..34e938f3 --- /dev/null +++ b/peripherals/sram/DE2_115.vhdl @@ -0,0 +1,361 @@ +library ieee; +library work; +use ieee.std_logic_1164.all; +use ieee.std_logic_misc.all; +use ieee.numeric_std.all; + +use work.decoder_types.all; + +entity DE2_115 is +generic ( + --! Num of 32-bits memory words + IMEMORY_WORDS : integer := 1024; --!= 4K (1024 * 4) bytes + DMEMORY_WORDS : integer := 1024 --!= 2k (512 * 2) bytes + ); + port ( + CLOCK_50 : in std_logic; + CLOCK2_50 : in std_logic; + CLOCK3_50 : in std_logic; + SMA_CLKIN : in std_logic; + SMA_CLKOUT : out std_logic; + LEDG : out std_logic_vector( 8 downto 0 ); + LEDR : out std_logic_vector( 17 downto 0 ); + KEY : in std_logic_vector( 3 downto 0 ); + EX_IO : inout std_logic_vector( 6 downto 0 ); + SW : in std_logic_vector( 17 downto 0 ); + HEX0 : out std_logic_vector( 6 downto 0 ); + HEX1 : out std_logic_vector( 6 downto 0 ); + HEX2 : out std_logic_vector( 6 downto 0 ); + HEX3 : out std_logic_vector( 6 downto 0 ); + HEX4 : out std_logic_vector( 6 downto 0 ); + HEX5 : out std_logic_vector( 6 downto 0 ); + HEX6 : out std_logic_vector( 6 downto 0 ); + HEX7 : out std_logic_vector( 6 downto 0 ); + LCD_BLON : out std_logic; + LCD_DATA : inout std_logic_vector( 7 downto 0 ); + LCD_EN : out std_logic; + LCD_ON : out std_logic; + LCD_RS : out std_logic; + LCD_RW : out std_logic; + UART_CTS : in std_logic; + UART_RTS : out std_logic; + UART_RXD : in std_logic; + UART_TXD : out std_logic; + PS2_CLK : inout std_logic; + PS2_CLK2 : inout std_logic; + PS2_DAT : inout std_logic; + PS2_DAT2 : inout std_logic; + SD_CLK : out std_logic; + SD_CMD : inout std_logic; + SD_DAT : inout std_logic_vector( 3 downto 0 ); + SD_WP_N : in std_logic; + VGA_B : out std_logic_vector( 7 downto 0 ); + VGA_BLANK_N : out std_logic; + VGA_CLK : out std_logic; + VGA_G : out std_logic_vector( 7 downto 0 ); + VGA_HS : out std_logic; + VGA_R : out std_logic_vector( 7 downto 0 ); + VGA_SYNC_N : out std_logic; + VGA_VS : out std_logic; + AUD_ADCDAT : in std_logic; + AUD_ADCLRCK : inout std_logic; + AUD_BCLK : inout std_logic; + AUD_DACDAT : out std_logic; + AUD_DACLRCK : inout std_logic; + AUD_XCK : out std_logic; + EEP_I2C_SCLK : out std_logic; + EEP_I2C_SDAT : inout std_logic; + I2C_SCLK : out std_logic; + I2C_SDAT : inout std_logic; + ENET0_GTX_CLK : out std_logic; + ENET0_INT_N : in std_logic; + ENET0_LINK100 : in std_logic; + ENET0_MDC : out std_logic; + ENET0_MDIO : inout std_logic; + ENET0_RST_N : out std_logic; + ENET0_RX_CLK : in std_logic; + ENET0_RX_COL : in std_logic; + ENET0_RX_CRS : in std_logic; + ENET0_RX_DATA : in std_logic_vector( 3 downto 0 ); + ENET0_RX_DV : in std_logic; + ENET0_RX_ER : in std_logic; + ENET0_TX_CLK : in std_logic; + ENET0_TX_DATA : out std_logic_vector( 3 downto 0 ); + ENET0_TX_EN : out std_logic; + ENET0_TX_ER : out std_logic; + ENETCLK_25 : in std_logic; + ENET1_GTX_CLK : out std_logic; + ENET1_INT_N : in std_logic; + ENET1_LINK100 : in std_logic; + ENET1_MDC : out std_logic; + ENET1_MDIO : inout std_logic; + ENET1_RST_N : out std_logic; + ENET1_RX_CLK : in std_logic; + ENET1_RX_COL : in std_logic; + ENET1_RX_CRS : in std_logic; + ENET1_RX_DATA : in std_logic_vector( 3 downto 0 ); + ENET1_RX_DV : in std_logic; + ENET1_RX_ER : in std_logic; + ENET1_TX_CLK : in std_logic; + ENET1_TX_DATA : out std_logic_vector( 3 downto 0 ); + ENET1_TX_EN : out std_logic; + ENET1_TX_ER : out std_logic; + TD_CLK27 : in std_logic; + TD_DATA : in std_logic_vector( 7 downto 0 ); + TD_HS : in std_logic; + TD_RESET_N : out std_logic; + TD_VS : in std_logic; + OTG_ADDR : out std_logic_vector( 1 downto 0 ); + OTG_CS_N : out std_logic; + OTG_DATA : inout std_logic_vector( 15 downto 0 ); + OTG_INT : in std_logic; + OTG_RD_N : out std_logic; + OTG_RST_N : out std_logic; + OTG_WE_N : out std_logic; + IRDA_RXD : in std_logic; + DRAM_ADDR : out std_logic_vector( 12 downto 0 ); + DRAM_BA : out std_logic_vector( 1 downto 0 ); + DRAM_CAS_N : out std_logic; + DRAM_CKE : out std_logic; + DRAM_CLK : out std_logic; + DRAM_CS_N : out std_logic; + DRAM_DQ : inout std_logic_vector( 31 downto 0 ); + DRAM_DQM : out std_logic_vector( 3 downto 0 ); + DRAM_RAS_N : out std_logic; + DRAM_WE_N : out std_logic; + SRAM_ADDR : out std_logic_vector( 19 downto 0 ); + SRAM_CE_N : out std_logic; + SRAM_DQ : inout std_logic_vector( 15 downto 0 ); + SRAM_LB_N : out std_logic; + SRAM_OE_N : out std_logic; + SRAM_UB_N : out std_logic; + SRAM_WE_N : out std_logic; + FL_ADDR : out std_logic_vector( 22 downto 0 ); + FL_CE_N : out std_logic; + FL_DQ : inout std_logic_vector( 7 downto 0 ); + FL_OE_N : out std_logic; + FL_RST_N : out std_logic; + FL_RY : in std_logic; + FL_WE_N : out std_logic; + FL_WP_N : out std_logic + ); +end entity; + + +architecture rtl of DE2_115 is + + signal clk : std_logic; + signal rst : std_logic; + + -- Instruction bus signals + signal idata : std_logic_vector(31 downto 0); + signal iaddress : integer range 0 to IMEMORY_WORDS-1 := 0; + signal address : std_logic_vector (9 downto 0); + + -- Data bus signals + signal daddress : integer range 0 to DMEMORY_WORDS-1; + signal ddata_r : std_logic_vector(31 downto 0); + signal ddata_w : std_logic_vector(31 downto 0); + signal dmask : std_logic_vector(3 downto 0); + signal dcsel : std_logic_vector(1 downto 0); + signal d_we : std_logic := '0'; + + signal ddata_r_mem : std_logic_vector(31 downto 0); + signal d_rd : std_logic; + + -- I/O signals + signal input_in : std_logic_vector(31 downto 0); + + -- PLL signals + signal locked_sig : std_logic; + + -- CPU state signals + signal state : cpu_state_t; + signal chipselect : STD_LOGIC; + signal write : STD_LOGIC; + signal read_address : unsigned(15 downto 0); + signal write_address : unsigned(15 downto 0); + signal q : STD_LOGIC_VECTOR(7 DOWNTO 0); + signal addressram : std_logic_vector(19 downto 0); + signal data_out : STD_LOGIC_VECTOR(15 DOWNTO 0); + signal data_in : STD_LOGIC_VECTOR(15 DOWNTO 0); + + signal clk_ram : std_logic; + +begin + + pll_inst: entity work.pll + port map( + areset => '0', + inclk0 => CLOCK_50, + c0 => clk, + locked => locked_sig + ); + + rst <= SW(9); + + -- Dummy out signals + DRAM_DQ <= ddata_r(31 downto 0); + --DRAM_DQ <= ddata_r(31 downto 16); + --LEDR(9) <= SW(9); + DRAM_ADDR(9 downto 0) <= address; + + -- IMem shoud be read from instruction and data buses + -- Not enough RAM ports for instruction bus, data bus and in-circuit programming + process(d_rd, dcsel, daddress, iaddress) + begin + if (d_rd = '1') and (dcsel = "00") then + address <= std_logic_vector(to_unsigned(daddress,10)); + else + address <= std_logic_vector(to_unsigned(iaddress,10)); + end if; + end process; + ------------------------------------ + chipselect <= '1'; + + addressram <= "01001111001001010000"; + clk_ram<= SW(17); + + sram: entity work.sram + port map( + SRAM_OE_N => SRAM_OE_N, + SRAM_WE_N => SRAM_WE_N, + SRAM_CE_N => SRAM_CE_N, + SRAM_ADDR => SRAM_ADDR, + SRAM_DQ => SRAM_DQ, + SRAM_UB_N => SRAM_UB_N, + SRAM_LB_N => SRAM_LB_N, + clk => clk_ram, + chipselect => chipselect, + write => write, + data_out => data_out, + address => addressram, + data_in => data_in + ); + + process (clk_ram) + begin + if rising_edge(clk_ram) then + if (SW(5) = '1') then + write <= '1'; + data_out <= "0000100001000111"; + LEDR(15 DOWNTO 0) <= "0000000000000000"; + else + write <= '0'; + LEDR(15 DOWNTO 0) <= data_in; + end if; + end if; + end process; + + + + ------------------------------------ + + -- 32-bits x 1024 words quartus RAM (dual port: portA -> riscV, portB -> In-System Mem Editor + iram_quartus_inst: entity work.iram_quartus + port map( + address => address, + byteena => "1111", + clock => clk, + data => (others => '0'), + wren => '0', + q => idata + ); + + -- Data Memory RAM + dmem: entity work.dmemory + generic map( + MEMORY_WORDS => DMEMORY_WORDS + ) + port map( + rst => rst, + clk => clk, + data => ddata_w, + address => daddress, + we => d_we, + csel => dcsel(0), + dmask => dmask, + q => ddata_r_mem + ); + + -- Adress space mux ((check sections.ld) -> Data chip select: + -- 0x00000 -> Instruction memory + -- 0x20000 -> Data memory + -- 0x40000 -> Input/Output generic address space + with dcsel select + ddata_r <= idata when "00", + ddata_r_mem when "01", + input_in when "10", + (others => '0') when others; + + -- Softcore instatiation + myRisc: entity work.core + generic map( + IMEMORY_WORDS => IMEMORY_WORDS, + DMEMORY_WORDS => DMEMORY_WORDS + ) + port map( + clk => clk, + rst => rst, + iaddress => iaddress, + idata => idata, + daddress => daddress, + ddata_r => ddata_r, + ddata_w => ddata_w, + d_we => d_we, + d_rd => d_rd, + dcsel => dcsel, + dmask => dmask, + state => state + ); + + -- Output register (Dummy LED blinky) + process(clk, rst) + begin + if rst = '1' then + --LEDR(3 downto 0) <= (others => '0'); + HEX0 <= (others => '1'); + HEX1 <= (others => '1'); + HEX2 <= (others => '1'); + HEX3 <= (others => '1'); + HEX4 <= (others => '1'); + HEX5 <= (others => '1'); + else + if rising_edge(clk) then + if (d_we = '1') and (dcsel = "10")then + -- ToDo: Simplify comparators + -- ToDo: Maybe use byte addressing? + -- x"01" (word addressing) is x"04" (byte addressing) + if to_unsigned(daddress, 32)(8 downto 0) = x"01" then + --LEDR(4 downto 0) <= ddata_w(4 downto 0); + elsif to_unsigned(daddress, 32)(8 downto 0) = x"02" then + HEX0 <= ddata_w(6 downto 0); + HEX1 <= ddata_w(13 downto 7); + HEX2 <= ddata_w(20 downto 14); + HEX3 <= ddata_w(27 downto 21); + HEX4 <= (others => '1'); + HEX5 <= (others => '1'); + end if; + end if; + end if; + end if; + end process; + + + -- Input register + process(clk, rst) + begin + if rst = '1' then + input_in <= (others => '0'); + else + if rising_edge(clk) then + input_in <= (others => '0'); + if (d_rd = '1') and (dcsel = "10") then + input_in(4 downto 0) <= SW(4 downto 0); + end if; + end if; + end if; + end process; + + +end; \ No newline at end of file diff --git a/peripherals/sram/README.md b/peripherals/sram/README.md new file mode 100644 index 00000000..e5627d6f --- /dev/null +++ b/peripherals/sram/README.md @@ -0,0 +1,46 @@ +## Controle SRAM DE2-115: + +Implementou-se o controle da SRAM externa, IS61WV102416BLL-10TLI, do módulo DE2-115. A SRAM em questão possui 2M bytes de memória. + +## Descrição dos pinos: + +| PINS | Descrição | +| ------------- |:-----------------------------------:| +| A0-A19 | Endereço de entrada | +| I/O0-1/O15 | Entrada e saída de dados | +| !CE | Saída de habilitação do chip | +| !OE | Output Enable Input | +| !WE | Write Enable Input | +| !LB | Lower-byte Control (I/O0-I/O7 | +| !UB | Upper-byte Control (I/O8-I/O15) | +| NC | Sem conexão | +| Vdd | Vdd power | +| GND | Terra | + +## Tabela da verdade da SRAM: + +![Alt text](https://github.com/marianegri/riscv-multicycle/blob/master/peripherals/sram_controle_DE2_115/tabela_verdade.jpg?raw=true) + +**Ciclo de Leitura** + +![Alt text](https://github.com/marianegri/riscv-multicycle/blob/master/peripherals/sram_controle_DE2_115/leitura.jpg?raw=true) + +**Ciclo de Escrita** + +![Alt text](https://github.com/marianegri/riscv-multicycle/blob/master/peripherals/sram_controle_DE2_115/escrita.jpg?raw=true) + + +## Resultados: +**Modelsim Simulação** + +![alt text](https://github.com/marianegri/riscv-multicycle/blob/master/peripherals/sram_controle_DE2_115/modelsim.png?raw=true "Resultados ModelSim") + +* Simulação com funcionamento adequado. +* Ao colocar no kit de desenvolvimento da altera percebe-se que a leitura não ocorre como o esperado. Possíveis causas: + * Sincronismo. + * Tempos de acionamento dos pinos diferente do esperado. + + +## Bibliografia +[DATASHEET](https://br.mouser.com/datasheet/2/198/61WV102416ALL-258682.pdf) + diff --git a/peripherals/sram/escrita.jpg b/peripherals/sram/escrita.jpg new file mode 100644 index 00000000..75840743 Binary files /dev/null and b/peripherals/sram/escrita.jpg differ diff --git a/peripherals/sram/leitura.jpg b/peripherals/sram/leitura.jpg new file mode 100644 index 00000000..a22f5a3b Binary files /dev/null and b/peripherals/sram/leitura.jpg differ diff --git a/peripherals/sram/modelsim.png b/peripherals/sram/modelsim.png new file mode 100644 index 00000000..e2412684 Binary files /dev/null and b/peripherals/sram/modelsim.png differ diff --git a/peripherals/sram/sram.vhd b/peripherals/sram/sram.vhd new file mode 100644 index 00000000..ca0a8b51 --- /dev/null +++ b/peripherals/sram/sram.vhd @@ -0,0 +1,112 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use ieee.std_logic_textio.all; +use std.textio.all; + +entity sram is + PORT( + SRAM_OE_N : out std_logic; + SRAM_WE_N : out std_logic; + SRAM_CE_N : out std_logic; + SRAM_ADDR : out std_logic_vector(19 downto 0); + SRAM_DQ : inout std_logic_vector(15 downto 0); + SRAM_UB_N : out std_logic; + SRAM_LB_N : out std_logic; + -- + + clk : IN STD_LOGIC; + chipselect : IN STD_LOGIC; + write : IN STD_LOGIC; + read : IN STD_LOGIC; + data_out : in STD_LOGIC_VECTOR(15 DOWNTO 0); + address : in std_logic_vector(19 downto 0); + --read_address : IN unsigned(15 downto 0); + --write_address : IN unsigned(15 downto 0); + --we : IN STD_LOGIC; + data_in : out STD_LOGIC_VECTOR(15 DOWNTO 0) + ); +end entity sram; + +architecture RTL of sram is + type mem_state_type is (IDLE, READ_M, WRITE_M, DONE); + signal mem_state : mem_state_type; + + --type reg_array is array (0 to 31) of std_logic_vector(7 downto 0); + --signal memory : reg_array; + +begin + SRAM_ADDR <= address(19 downto 0); + + memory_state : process(clk) + begin + if rising_edge(clk) then + case mem_state is + when IDLE => + + if chipselect = '1' then + + if write = '1' then + mem_state <= WRITE_M; + end if; + if read = '1' then + mem_state <= READ_M; + end if; + + end if; + + when WRITE_M => + mem_state <= DONE; + + when READ_M => + mem_state <= DONE; + + when DONE => + mem_state <= IDLE; + + end case; + end if; + + end process; + + memory_state_output : process(mem_state, SRAM_DQ, data_out) + begin + + SRAM_CE_N <= '1'; + --SRAM_LB_N <= '0'; + --SRAM_UB_N <= '0'; + --SRAM_WE_N <= '0'; + --SRAM_OE_N <= '0'; + + case mem_state is + + when IDLE => + SRAM_WE_N <= '1'; + SRAM_CE_N <= '0'; + SRAM_OE_N <= '1'; + SRAM_LB_N <= '0'; + SRAM_UB_N <= '0'; + + when READ_M => + SRAM_WE_N <= '1'; + SRAM_CE_N <= '0'; + SRAM_OE_N <= '0'; + SRAM_LB_N <= '0'; + SRAM_UB_N <= '1'; + data_in <= SRAM_DQ; + + when WRITE_M => + SRAM_OE_N <= '0'; + SRAM_CE_N <= '0'; + SRAM_WE_N <= '0'; + SRAM_LB_N <= '0'; + SRAM_UB_N <= '1'; + SRAM_DQ <= data_out; + + when DONE => + + end case; + end process; + + +end architecture RTL; diff --git a/peripherals/sram/tabela_verdade.jpg b/peripherals/sram/tabela_verdade.jpg new file mode 100644 index 00000000..e702945a Binary files /dev/null and b/peripherals/sram/tabela_verdade.jpg differ diff --git a/peripherals/sram/tb.do b/peripherals/sram/tb.do new file mode 100644 index 00000000..4a3c0b0d --- /dev/null +++ b/peripherals/sram/tb.do @@ -0,0 +1,44 @@ +# ============================================================================ +# Name : tb_divisor.do +# Author : Renan Augusto Starke +# Version : 0.1 +# Copyright : Renan, Departamento de Eletrônica, Florianópolis, IFSC +# Description : Exemplo de script de compilação ModelSim para divisor de clock +# ============================================================================ + + +#Cria biblioteca do projeto +vlib work + +#compila projeto: todos os aquivo. Ordem é importante +vcom sram.vhd tb_sram.vhd + +#Simula (work é o diretorio, testbench é o nome da entity) +vsim -t ns work.tb_sram + +#Mosta forma de onda +view wave + +#Adiciona ondas específicas +# -radix: binary, hex, dec +# -label: nome da forma de onda +add wave -radix dec /clk +add wave -radix binary /write +add wave -radix binary /address +add wave -radix binary /SRAM_OE_N +add wave -radix binary /SRAM_WE_N +add wave -radix binary /SRAM_CE_N +add wave -radix binary /SRAM_ADDR +add wave -radix binary /SRAM_DQ +add wave -radix binary /SRAM_UB_N +add wave -radix binary /SRAM_LB_N +add wave -radix binary /data_in +add wave -radix binary /data_out +#Como mostrar sinais internos do processo + + +#Simula até um 500ns +run 500ns + +wave zoomfull +write wave wave.ps \ No newline at end of file diff --git a/peripherals/sram/tb_sram.vhd b/peripherals/sram/tb_sram.vhd new file mode 100644 index 00000000..e079d6c2 --- /dev/null +++ b/peripherals/sram/tb_sram.vhd @@ -0,0 +1,140 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity tb_sram is +end entity tb_sram; + +architecture RTL of tb_sram is + component sram + PORT( + SRAM_OE_N : out std_logic; + SRAM_WE_N : out std_logic; + SRAM_CE_N : out std_logic; + SRAM_ADDR : out std_logic_vector(19 downto 0); + SRAM_DQ : inout std_logic_vector(15 downto 0); + SRAM_UB_N : out std_logic; + SRAM_LB_N : out std_logic; + -- + + clk : IN STD_LOGIC; + chipselect : IN STD_LOGIC; + write : IN STD_LOGIC; + read : IN STD_LOGIC; + data_in : out STD_LOGIC_VECTOR(15 DOWNTO 0); + address : in std_logic_vector(19 downto 0); + --read_address : IN unsigned(15 downto 0); + --write_address : IN unsigned(15 downto 0); + --we : IN STD_LOGIC; + data_out : in STD_LOGIC_VECTOR(15 DOWNTO 0) + ); + end component sram; + + signal SRAM_OE_N : std_logic; + signal SRAM_WE_N : std_logic; + signal SRAM_CE_N : std_logic; + signal SRAM_ADDR : std_logic_vector(19 downto 0); + signal SRAM_DQ : std_logic_vector(15 downto 0); + signal SRAM_UB_N : std_logic; + signal SRAM_LB_N : std_logic; + -- + + signal clk : STD_LOGIC; + signal chipselect : STD_LOGIC; + signal write : STD_LOGIC; + signal read : STD_LOGIC; + signal address : std_logic_vector(19 downto 0); + signal data_in : STD_LOGIC_VECTOR(15 DOWNTO 0); + signal data_out : STD_LOGIC_VECTOR(15 DOWNTO 0); + + +begin + + dut: sram + port map( + SRAM_OE_N =>SRAM_OE_N, + SRAM_WE_N => SRAM_WE_N, + SRAM_CE_N => SRAM_CE_N, + SRAM_ADDR => SRAM_ADDR, + SRAM_DQ => SRAM_DQ, + SRAM_UB_N => SRAM_UB_N, + SRAM_LB_N => SRAM_LB_N, + + clk => clk, + chipselect => chipselect, + write => write, + read => read, + data_in => data_in, + data_out => data_out, + address => address + ); + + address <= "00000100001000000010"; + data_out <= "0010001000010001"; + chipselect <= '1'; + + process + begin + clk <= '0'; + + wait for 10 ns; + clk <= '1'; + + wait for 10 ns; + clk <= '0'; + write <= '1'; + wait for 10 ns; + clk <= '1'; + + wait for 10 ns; + clk <= '0'; + wait for 10 ns; + clk <= '1'; + + wait for 10 ns; + clk <= '0'; + wait for 10 ns; + clk <= '1'; + + wait for 10 ns; + clk <= '0'; + read <= '1'; + wait for 10 ns; + clk <= '1'; + + wait for 10 ns; + clk <= '0'; + read <= '1'; + + wait for 10 ns; + clk <= '1'; + + wait for 10 ns; + clk <= '0'; + wait for 10 ns; + clk <= '1'; + + wait for 10 ns; + clk <= '0'; + wait for 10 ns; + clk <= '1'; + + wait for 10 ns; + clk <= '0'; + wait for 10 ns; + clk <= '1'; + + wait for 10 ns; + clk <= '0'; + read <= '1'; + wait for 10 ns; + clk <= '1'; + + wait for 10 ns; + clk <= '0'; + read <= '1'; + + wait; + end process; + +end architecture RTL; diff --git a/peripherals/sram/testbench.do b/peripherals/sram/testbench.do new file mode 100644 index 00000000..d0b4cc77 --- /dev/null +++ b/peripherals/sram/testbench.do @@ -0,0 +1,116 @@ + +#****************************************************************************** +# * +# Copyright (C) 2019 IFSC * +# * +# * +# All information provided herein is provided on an "as is" basis, * +# without warranty of any kind. * +# * +# File Name: testbench.do * +# * +# Function: riscv muticycle simulation script * +# * +# REVISION HISTORY: * +# Revision 0.1.0 08/01/2018 - Initial Revision * +#****************************************************************************** + +vlib work +# vcom ./../memory/imemory.vhd +# vcom ./../memory/imemory_load.vhd +vcom ./../../memory/iram_quartus.vhd +vcom ./../../memory/dmemory.vhd +vcom ./../../alu/alu_types.vhd +vcom ./../../alu/alu.vhd +vcom ./../../alu/m/M_types.vhd +vcom ./../../alu/m/M.vhd +vcom ./../../decoder/decoder_types.vhd +vcom ./../../decoder/iregister.vhd +vcom ./../../decoder/decoder.vhd +vcom ./../../registers/register_file.vhd +vcom ./../../core/core.vhd +vcom ./../../core/txt_util.vhdl +vcom ./../../core/trace_debug.vhd +vcom ./sram.vhd + +# vcom ./uart/uart.vhd +# vcom ./vga/vga_controller.vhd ./vga/vga_buffer.vhd +# vcom ./sdram/sim/mti_pkg.vhd ./sdram/sim/mt48lc8m16a2.vhd ./sdram/sdram_controller.vhd +vcom ./testbench.vhd + +vsim -t ns work.coretestbench + +view wave +add wave -radix binary /clk +add wave -radix binary /rst +add wave -height 15 -divider "Instruction Memory" +add wave -label iAddr -radix hex /address +add wave -label iWord -radix hex idata +add wave -label decoded -radix ASCII /debugString +# add wave /debugString +# add wave -radix hex /imem/RAM +# add wave -radix hex /q + +add wave -height 15 -divider "PC and Ctrl Targers" +add wave -radix hex -label pc /myRiscv/pc +add wave -radix hex -label jal_target /myRiscv/jal_target +add wave -radix hex -label jalr_target /myRiscv/jalr_target +add wave -label branch_cmp /myRiscv/branch_cmp + +add wave -height 15 -divider "Iregister debug" +add wave -label opcode /myRiscv/opcodes +add wave -label rd /myRiscv/rd +add wave -label rs1 /myRiscv/rs1 +add wave -label rs2 /myRiscv/rs2 +add wave -label imm_i /myRiscv/imm_i +add wave -label imm_s /myRiscv/imm_s +add wave -label imm_b /myRiscv/imm_b +add wave -label imm_u /myRiscv/imm_u +add wave -label imm_j /myRiscv/imm_j + + +add wave -height 15 -divider "Register file debug" + add wave -label registers -radix hex /myRiscv/registers/ram + add wave -label w_ena /myRiscv/rf_w_ena + add wave -label w_data -radix hex /myRiscv/rw_data + add wave -label r1_data -radix hex /myRiscv/rs1_data + add wave -label r2_data -radix hex /myRiscv/rs2_data + +# decoder debug +add wave -label states /myRiscv/decoder0/state + +# add wave -height 15 -divider "Alu debug" +# add wave -label aluData /myRiscv/alu_data +#add wave -label aluOut /myRiscv/alu_out + +add wave -height 15 -divider "Data memory debug" +add wave -label daddr -radix hex /myRiscv/memAddrTypeSBlock/addr +add wave -label fsm_data -radix hex /dmem/fsm_data +add wave -label ram_data -radix hex /dmem/ram_data +add wave -label mState /dmem/state +add wave -label fsm_we /dmem/fsm_we +add wave -label ddata_r_mem -radix hex /dmem/q +add wave -label datamemory -radix hex /dmem/ram_block + + +add wave -height 15 -divider "Data bus" +add wave -label daddress -radix hex /daddress +add wave -label ddata_r -radix hex /ddata_r +add wave -label ddata_w -radix hex /ddata_w +add wave -label dmask -radix bin /dmask +add wave -label dcsel /dcsel +add wave -label d_we /d_we +add wave -label d_rd /d_rd +add wave -label d_sig /d_sig + +add wave -height 15 -divider "Input/Output SIM" +add wave -label LEDR -radix hex /LEDR +add wave -label ARDUINO_IO -radix hex /ARDUINO_IO + +add wave -label data_out_SRAM /data_out_SRAM +add wave -label data_in_SRAM /data_in_SRAM +add wave -label chipselect /chipselect +add wave -label write /write +add wave -label read /read + +run 950000 ns diff --git a/peripherals/sram/testbench.vhd b/peripherals/sram/testbench.vhd new file mode 100644 index 00000000..916eb927 --- /dev/null +++ b/peripherals/sram/testbench.vhd @@ -0,0 +1,319 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +use work.decoder_types.all; + +entity coretestbench is + generic( + --! Num of 32-bits memory words + IMEMORY_WORDS : integer := 1024; --!= 4K (1024 * 4) bytes + DMEMORY_WORDS : integer := 1024; --!= 2k (512 * 2) bytes + constant SIZE : integer := 8 -- 8 bytes UART package + ); + + port( + ----------- SEG7 ------------ + HEX0 : out std_logic_vector(7 downto 0); + HEX1 : out std_logic_vector(7 downto 0); + HEX2 : out std_logic_vector(7 downto 0); + HEX3 : out std_logic_vector(7 downto 0); + HEX4 : out std_logic_vector(7 downto 0); + HEX5 : out std_logic_vector(7 downto 0); + ----------- SW ------------ + + SW : in std_logic_vector(9 downto 0); + LEDR : out std_logic_vector(9 downto 0); + ---------- ARDUINO IO ----- + ARDUINO_IO : inout std_logic_vector(15 downto 0) + ); + +end entity coretestbench; + +architecture RTL of coretestbench is + signal clk : std_logic; + signal clk_sdram : std_logic; + signal clk_vga : std_logic; + signal rst : std_logic; + signal rst_n : std_logic; + + signal idata : std_logic_vector(31 downto 0); + + signal daddress : natural; + signal ddata_r : std_logic_vector(31 downto 0); + signal ddata_w : std_logic_vector(31 downto 0); + signal dmask : std_logic_vector(3 downto 0); + signal dcsel : std_logic_vector(1 downto 0); + signal d_we : std_logic := '0'; + + signal iaddress : integer range 0 to IMEMORY_WORDS - 1 := 0; + + signal address : std_logic_vector(31 downto 0); + + signal ddata_r_mem : std_logic_vector(31 downto 0); + signal d_rd : std_logic; + + signal input_in : std_logic_vector(31 downto 0); + signal cpu_state : cpu_state_t; + + signal debugString : string(1 to 40) := (others => '0'); + + -- UART Signals + signal clk_baud : std_logic; + signal data_in : std_logic_vector(7 downto 0); + signal tx : std_logic; + signal start : std_logic; + signal tx_cmp : std_logic; + signal data_out : std_logic_vector(SIZE - 1 downto 0); + signal rx : std_logic; + signal rx_cmp : std_logic; + + signal csel_uart : std_logic; + + signal dmemory_address : natural; + signal d_sig : std_logic; + + -- SRAM + signal state : cpu_state_t; + signal chipselect : STD_LOGIC; + signal write : STD_LOGIC; + signal read_address : unsigned(15 downto 0); + signal write_address : unsigned(15 downto 0); + signal q : STD_LOGIC_VECTOR(7 DOWNTO 0); + signal addressram : std_logic_vector(19 downto 0); + + signal clk_ram : std_logic; + signal SRAM_OE_N : std_logic; + signal SRAM_WE_N : std_logic; + signal SRAM_CE_N : std_logic; + signal SRAM_ADDR : std_logic_vector(19 downto 0); + signal SRAM_DQ : std_logic_vector(15 downto 0); + signal SRAM_UB_N : std_logic; + signal SRAM_LB_N : std_logic; + signal data_out_SRAM : STD_LOGIC_VECTOR(31 DOWNTO 0); + signal data_in_SRAM : STD_LOGIC_VECTOR(15 DOWNTO 0); + signal teste : std_logic; + signal read : STD_LOGIC; + +begin + + clock_driver : process + constant period : time := 1000 ns; + begin + clk <= '0'; + wait for period / 2; + clk <= '1'; + wait for period / 2; + end process clock_driver; + + reset : process is + begin + rst <= '1'; + wait for 5 ns; + rst <= '0'; + wait; + end process reset; + + -- Dummy out signals + -- ARDUINO_IO <= ddata_r(31 downto 16); + + -- imem: component imemory + -- generic map( + -- MEMORY_WORDS => IMEMORY_WORDS + -- ) + -- port map( + -- clk => clk, + -- data => idata, + -- write_address => 0, + -- read_address => iaddress, + -- we => '0', + -- q => idata + -- ); + + rst_n <= not rst; + + -- imem: component imemory + -- generic map( + -- MEMORY_WORDS => IMEMORY_WORDS + -- ) + -- port map( + -- clk => clk, + -- data => idata, + -- write_address => 0, + -- read_address => iaddress, + -- we => '0', + -- q => idata + -- ); + + -- IMem shoud be read from instruction and data buses + -- Not enough RAM ports for instruction bus, data bus and in-circuit programming + -- with dcsel select + -- address <= std_logic_vector(to_unsigned(daddress,10)) when "01", + -- std_logic_vector(to_unsigned(iaddress,10)) when others; + process(d_rd, dcsel, daddress, iaddress) + begin + if (d_rd = '1') and (dcsel = "00") then + address <= std_logic_vector(to_unsigned(daddress, 32)); + else + address <= std_logic_vector(to_unsigned(iaddress, 32)); + end if; + end process; + + -- 32-bits x 1024 words quartus RAM (dual port: portA -> riscV, portB -> In-System Mem Editor + iram_quartus_inst : entity work.iram_quartus + port map( + address => address(9 downto 0), + byteena => "1111", + clock => clk, + data => (others => '0'), + wren => '0', + q => idata + ); + + dmemory_address <= to_integer(to_unsigned(daddress, 10)); + -- Data Memory RAM + dmem : entity work.dmemory + generic map( + MEMORY_WORDS => DMEMORY_WORDS + ) + port map( + rst => rst, + clk => clk, + data => ddata_w, + address => dmemory_address, + we => d_we, + signal_ext => d_sig, + csel => dcsel(0), + dmask => dmask, + q => ddata_r_mem + ); + + addressram <= std_logic_vector(to_unsigned(daddress, 21)(19 downto 0)); + + sram : entity work.sram + port map( + SRAM_OE_N => SRAM_OE_N, + SRAM_WE_N => SRAM_WE_N, + SRAM_CE_N => SRAM_CE_N, + SRAM_ADDR => SRAM_ADDR, + SRAM_DQ => SRAM_DQ, + SRAM_UB_N => SRAM_UB_N, + SRAM_LB_N => SRAM_LB_N, + clk => clk, + chipselect => dcsel(0), + write => write, + read => read, + data_out => data_out_SRAM(15 downto 0), + address => addressram, + data_in => data_in_SRAM + ); + + process(clk) + begin + if rising_edge(clk) then + + if (dcsel = "11") then + if(d_we = '1')then + data_out_SRAM <= ddata_w; + end if; + write <= d_we; + read <= d_rd; + + end if; + end if; + end process; + + -- Adress space mux ((check sections.ld) -> Data chip select: + -- 0x00000 -> Instruction memory + -- 0x20000 -> Data memory + -- 0x40000 -> Input/Output generic address space + -- 0x60000 -> SDRAM address space + with dcsel select ddata_r <= + data_out_SRAM when "11",(others => '0') when others; + + -- Softcore instatiation + myRiscv : entity work.core + generic map( + IMEMORY_WORDS => IMEMORY_WORDS, + DMEMORY_WORDS => DMEMORY_WORDS + ) + port map( + clk => clk, + rst => rst, + iaddress => iaddress, + idata => idata, + daddress => daddress, + ddata_r => ddata_r, + ddata_w => ddata_w, + d_we => d_we, + d_rd => d_rd, + d_sig => d_sig, + dcsel => dcsel, + dmask => dmask, + state => cpu_state + ); + + -- Output register (Dummy LED blinky) + process(clk, rst) + begin + if rst = '1' then + LEDR(7 downto 0) <= (others => '0'); + HEX0 <= (others => '1'); + HEX1 <= (others => '1'); + HEX2 <= (others => '1'); + HEX3 <= (others => '1'); + HEX4 <= (others => '1'); + HEX5 <= (others => '1'); + else + if rising_edge(clk) then + if (d_we = '1') and (dcsel = "10") then + -- ToDo: Simplify compartors + -- ToDo: Maybe use byte addressing? + -- x"01" (word addressing) is x"04" (byte addressing) + if to_unsigned(daddress, 32)(8 downto 0) = x"01" then + LEDR(7 downto 0) <= ddata_w(7 downto 0); + elsif to_unsigned(daddress, 32)(8 downto 0) = x"02" then + HEX0 <= ddata_w(7 downto 0); + HEX1 <= ddata_w(15 downto 8); + HEX2 <= ddata_w(23 downto 16); + HEX3 <= ddata_w(31 downto 24); + -- HEX4 <= ddata_w(7 downto 0); + -- HEX5 <= ddata_w(7 downto 0); + end if; + end if; + end if; + end if; + end process; + + -- Input register + process(clk, rst) + begin + if rst = '1' then + input_in <= (others => '0'); + else + + if rising_edge(clk) then + if (d_rd = '1') and (dcsel = "10") then + if to_unsigned(daddress, 32)(8 downto 0) = x"00" then + input_in(4 downto 0) <= SW(4 downto 0); + elsif to_unsigned(daddress, 32)(8 downto 0) = x"04" then + input_in(7 downto 0) <= data_out; + end if; + end if; + end if; + end if; + + end process; + + -- FileOutput DEBUG + debug : entity work.trace_debug + generic map( + MEMORY_WORDS => IMEMORY_WORDS + ) + port map( + pc => iaddress, + data => idata, + inst => debugString + ); + +end architecture RTL;