URL
https://opencores.org/ocsvn/mblite/mblite/trunk
Subversion Repositories mblite
Compare Revisions
- This comparison shows the changes necessary to convert path
/mblite/trunk/designs
- from Rev 6 to Rev 8
- ↔ Reverse comparison
Rev 6 → Rev 8
/core_wb/testbench.vhd
12,151 → 12,151
-- |
---------------------------------------------------------------------------------------------- |
|
LIBRARY ieee; |
USE ieee.std_logic_1164.ALL; |
USE ieee.std_logic_unsigned.ALL; |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
|
LIBRARY mblite; |
USE mblite.config_Pkg.ALL; |
USE mblite.core_Pkg.ALL; |
USE mblite.std_Pkg.ALL; |
library mblite; |
use mblite.config_Pkg.all; |
use mblite.core_Pkg.all; |
use mblite.std_Pkg.all; |
|
use std.textio.all; |
|
ENTITY testbench IS |
END testbench; |
entity testbench is |
end testbench; |
|
ARCHITECTURE arch OF testbench IS |
architecture arch of testbench is |
|
SIGNAL imem_o : imem_out_type; |
SIGNAL imem_i : imem_in_type; |
signal imem_o : imem_out_type; |
signal imem_i : imem_in_type; |
|
SIGNAL wb_o : wb_mst_out_type; |
SIGNAL wb_i : wb_mst_in_type; |
signal wb_o : wb_mst_out_type; |
signal wb_i : wb_mst_in_type; |
|
SIGNAL sys_clk_i : std_logic := '0'; |
SIGNAL sys_int_i : std_logic; |
SIGNAL sys_rst_i : std_logic; |
signal sys_clk_i : std_logic := '0'; |
signal sys_int_i : std_logic; |
signal sys_rst_i : std_logic; |
|
CONSTANT std_out_adr : std_logic_vector(CFG_DMEM_SIZE - 1 DOWNTO 0) := X"FFFFFFC0"; |
SIGNAL std_out_ack : std_logic; |
constant std_out_adr : std_logic_vector(CFG_DMEM_SIZE - 1 downto 0) := X"FFFFFFC0"; |
signal std_out_ack : std_logic; |
|
SIGNAL stdo_ena : std_logic; |
signal stdo_ena : std_logic; |
|
SIGNAL dmem_ena : std_logic; |
SIGNAL dmem_dat : std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0); |
SIGNAL dmem_sel : std_logic_vector(3 DOWNTO 0); |
signal dmem_ena : std_logic; |
signal dmem_dat : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0); |
signal dmem_sel : std_logic_vector(3 downto 0); |
|
CONSTANT rom_size : integer := 16; |
CONSTANT ram_size : integer := 16; |
constant rom_size : integer := 16; |
constant ram_size : integer := 16; |
|
BEGIN |
begin |
|
sys_clk_i <= NOT sys_clk_i AFTER 10000 ps; |
sys_rst_i <= '1' AFTER 0 ps, '0' AFTER 150000 ps; |
sys_int_i <= '1' AFTER 500000000 ps, '0' after 500040000 ps; |
sys_clk_i <= not sys_clk_i after 10000 ps; |
sys_rst_i <= '1' after 0 ps, '0' after 150000 ps; |
sys_int_i <= '1' after 500000000 ps, '0' after 500040000 ps; |
|
timeout: PROCESS(sys_clk_i) |
BEGIN |
IF NOW = 10 ms THEN |
report "TIMEOUT" SEVERITY FAILURE; |
END IF; |
timeout: process(sys_clk_i) |
begin |
if NOW = 10 ms then |
report "TIMEOUT" severity FAILURE; |
end if; |
|
-- BREAK ON EXIT (0xB8000000) |
IF compare(imem_i.dat_i, "10111000000000000000000000000000") = '1' THEN |
if compare(imem_i.dat_i, "10111000000000000000000000000000") = '1' then |
-- Make sure the simulator finishes when an error is encountered. |
-- For modelsim: see menu Simulate -> Runtime options -> Assertions |
REPORT "FINISHED" SEVERITY FAILURE; |
END IF; |
END PROCESS; |
report "FINISHED" severity FAILURE; |
end if; |
end process; |
|
-- Character device |
wb_stdio_slave: PROCESS(sys_clk_i) |
VARIABLE s : line; |
VARIABLE byte : std_logic_vector(7 DOWNTO 0); |
VARIABLE char : character; |
BEGIN |
IF rising_edge(sys_clk_i) THEN |
IF (wb_o.stb_o AND wb_o.cyc_o AND compare(wb_o.adr_o, std_out_adr)) = '1' THEN |
IF wb_o.we_o = '1' AND std_out_ack = '0' THEN |
wb_stdio_slave: process(sys_clk_i) |
variable s : line; |
variable byte : std_logic_vector(7 downto 0); |
variable char : character; |
begin |
if rising_edge(sys_clk_i) then |
if (wb_o.stb_o and wb_o.cyc_o and compare(wb_o.adr_o, std_out_adr)) = '1' then |
if wb_o.we_o = '1' and std_out_ack = '0' then |
-- WRITE STDOUT |
std_out_ack <= '1'; |
CASE wb_o.sel_o IS |
WHEN "0001" => byte := wb_o.dat_o( 7 DOWNTO 0); |
WHEN "0010" => byte := wb_o.dat_o(15 DOWNTO 8); |
WHEN "0100" => byte := wb_o.dat_o(23 DOWNTO 16); |
WHEN "1000" => byte := wb_o.dat_o(31 DOWNTO 24); |
WHEN OTHERS => NULL; |
END CASE; |
case wb_o.sel_o is |
when "0001" => byte := wb_o.dat_o( 7 downto 0); |
when "0010" => byte := wb_o.dat_o(15 downto 8); |
when "0100" => byte := wb_o.dat_o(23 downto 16); |
when "1000" => byte := wb_o.dat_o(31 downto 24); |
when others => null; |
end case; |
char := character'val(my_conv_integer(byte)); |
IF byte = X"0D" THEN |
if byte = X"0D" then |
-- Ignore character 13 |
ELSIF byte = X"0A" THEN |
elsif byte = X"0A" then |
-- Writeline on character 10 (newline) |
writeline(output, s); |
ELSE |
else |
-- Write to buffer |
write(s, char); |
END IF; |
ELSIF std_out_ack = '0' THEN |
end if; |
elsif std_out_ack = '0' then |
std_out_ack <= '1'; |
END IF; |
ELSE |
end if; |
else |
std_out_ack <= '0'; |
END IF; |
END IF; |
end if; |
end if; |
|
END PROCESS; |
end process; |
|
wb_i.clk_i <= sys_clk_i; |
wb_i.rst_i <= sys_rst_i; |
wb_i.int_i <= sys_int_i; |
|
dmem_ena <= wb_o.stb_o AND wb_o.cyc_o AND NOT compare(wb_o.adr_o, std_out_adr); |
dmem_ena <= wb_o.stb_o and wb_o.cyc_o and not compare(wb_o.adr_o, std_out_adr); |
|
PROCESS(wb_o.stb_o, wb_o.cyc_o, std_out_ack, wb_o.adr_o) |
BEGIN |
IF NOT compare(wb_o.adr_o, std_out_adr) = '1' THEN |
wb_i.ack_i <= wb_o.stb_o AND wb_o.cyc_o AFTER 2 ns; |
ELSE |
wb_i.ack_i <= std_out_ack AFTER 22 ns; |
END IF; |
END PROCESS; |
process(wb_o.stb_o, wb_o.cyc_o, std_out_ack, wb_o.adr_o) |
begin |
if not compare(wb_o.adr_o, std_out_adr) = '1' then |
wb_i.ack_i <= wb_o.stb_o and wb_o.cyc_o after 2 ns; |
else |
wb_i.ack_i <= std_out_ack after 22 ns; |
end if; |
end process; |
|
imem : sram GENERIC MAP |
imem : sram generic map |
( |
WIDTH => CFG_IMEM_WIDTH, |
SIZE => rom_size - 2 |
) |
PORT MAP |
port map |
( |
dat_o => imem_i.dat_i, |
dat_i => "00000000000000000000000000000000", |
adr_i => imem_o.adr_o(rom_size - 1 DOWNTO 2), |
adr_i => imem_o.adr_o(rom_size - 1 downto 2), |
wre_i => '0', |
ena_i => imem_o.ena_o, |
clk_i => sys_clk_i |
); |
|
dmem_sel <= wb_o.sel_o WHEN wb_o.we_o = '1' ELSE (OTHERS => '0'); |
wb_i.dat_i <= X"61616161" WHEN std_out_ack = '1' ELSE dmem_dat; |
dmem_sel <= wb_o.sel_o when wb_o.we_o = '1' else (others => '0'); |
wb_i.dat_i <= X"61616161" when std_out_ack = '1' else dmem_dat; |
|
dmem : sram_4en GENERIC MAP |
dmem : sram_4en generic map |
( |
WIDTH => CFG_DMEM_WIDTH, |
SIZE => ram_size - 2 |
) |
PORT MAP |
port map |
( |
dat_o => dmem_dat, |
dat_i => wb_o.dat_o, |
adr_i => wb_o.adr_o(ram_size - 1 DOWNTO 2), |
adr_i => wb_o.adr_o(ram_size - 1 downto 2), |
wre_i => dmem_sel, |
ena_i => dmem_ena, |
clk_i => sys_clk_i |
); |
|
core_wb0 : core_wb PORT MAP |
core_wb0 : core_wb port map |
( |
imem_o => imem_o, |
wb_o => wb_o, |
164,4 → 164,4
wb_i => wb_i |
); |
|
END arch; |
end arch; |
/core_wb/config_Pkg.vhd
11,52 → 11,52
-- |
---------------------------------------------------------------------------------------------- |
|
LIBRARY ieee; |
USE ieee.std_logic_1164.ALL; |
USE ieee.std_logic_unsigned.ALL; |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
|
PACKAGE config_Pkg IS |
package config_Pkg is |
|
---------------------------------------------------------------------------------------------- |
-- CORE PARAMETERS |
---------------------------------------------------------------------------------------------- |
-- Implement external interrupt |
CONSTANT CFG_INTERRUPT : boolean := true; -- Disable or enable external interrupt [0,1] |
constant CFG_INTERRUPT : boolean := true; -- Disable or enable external interrupt [0,1] |
|
-- Implement hardware multiplier |
CONSTANT CFG_USE_HW_MUL : boolean := true; -- Disable or enable multiplier [0,1] |
constant CFG_USE_HW_MUL : boolean := true; -- Disable or enable multiplier [0,1] |
|
-- Implement hardware barrel shifter |
CONSTANT CFG_USE_BARREL : boolean := true; -- Disable or enable barrel shifter [0,1] |
constant CFG_USE_BARREL : boolean := true; -- Disable or enable barrel shifter [0,1] |
|
-- Debug mode |
CONSTANT CFG_DEBUG : boolean := true; -- Resets some extra registers for better readability |
constant CFG_DEBUG : boolean := true; -- Resets some extra registers for better readability |
-- and enables feedback (report) [0,1] |
-- Set CFG_DEBUG to zero to obtain best performance. |
|
-- Memory parameters |
CONSTANT CFG_DMEM_SIZE : positive := 32; -- Data memory bus size in 2LOG # elements |
CONSTANT CFG_IMEM_SIZE : positive := 16; -- Instruction memory bus size in 2LOG # elements |
CONSTANT CFG_BYTE_ORDER : boolean := true; -- Switch between MSB (1, default) and LSB (0) byte order policy |
constant CFG_DMEM_SIZE : positive := 32; -- Data memory bus size in 2LOG # elements |
constant CFG_IMEM_SIZE : positive := 16; -- Instruction memory bus size in 2LOG # elements |
constant CFG_BYTE_ORDER : boolean := true; -- Switch between MSB (1, default) and LSB (0) byte order policy |
|
-- Register parameters |
CONSTANT CFG_REG_FORCE_ZERO : boolean := true; -- Force data to zero if register address is zero [0,1] |
CONSTANT CFG_REG_FWD_WB : boolean := true; -- Forward writeback to loosen register memory requirements [0,1] |
CONSTANT CFG_MEM_FWD_WB : boolean := true; -- Forward memory result in stead of introducing stalls [0,1] |
constant CFG_REG_FORCE_ZERO : boolean := true; -- Force data to zero if register address is zero [0,1] |
constant CFG_REG_FWD_WRB : boolean := true; -- Forward writeback to loosen register memory requirements [0,1] |
constant CFG_MEM_FWD_WRB : boolean := true; -- Forward memory result in stead of introducing stalls [0,1] |
|
---------------------------------------------------------------------------------------------- |
-- CONSTANTS (currently not configurable / not tested) |
---------------------------------------------------------------------------------------------- |
CONSTANT CFG_DMEM_WIDTH : positive := 32; -- Data memory width in bits |
CONSTANT CFG_IMEM_WIDTH : positive := 32; -- Instruction memory width in bits |
CONSTANT CFG_GPRF_SIZE : positive := 5; -- General Purpose Register File Size in 2LOG # elements |
constant CFG_DMEM_WIDTH : positive := 32; -- Data memory width in bits |
constant CFG_IMEM_WIDTH : positive := 32; -- Instruction memory width in bits |
constant CFG_GPRF_SIZE : positive := 5; -- General Purpose Register File Size in 2LOG # elements |
|
---------------------------------------------------------------------------------------------- |
-- BUS PARAMETERS |
---------------------------------------------------------------------------------------------- |
|
TYPE memory_map_type IS ARRAY(natural RANGE <>) OF std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0); |
CONSTANT CFG_NUM_SLAVES : positive := 2; |
CONSTANT CFG_MEMORY_MAP : memory_map_type(0 TO CFG_NUM_SLAVES) := (X"00000000", X"00FFFFFF", X"FFFFFFFF"); |
type memory_map_type is array(natural range <>) of std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0); |
constant CFG_NUM_SLAVES : positive := 2; |
constant CFG_MEMORY_MAP : memory_map_type(0 to CFG_NUM_SLAVES) := (X"00000000", X"00FFFFFF", X"FFFFFFFF"); |
|
END config_Pkg; |
end config_Pkg; |
/core_syn/testbench.vhd
11,52 → 11,52
-- |
---------------------------------------------------------------------------------------------- |
|
LIBRARY ieee; |
USE ieee.std_logic_1164.ALL; |
USE ieee.std_logic_unsigned.ALL; |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
|
LIBRARY std; |
USE std.textio.ALL; |
library std; |
use std.textio.all; |
|
LIBRARY mblite; |
USE mblite.config_Pkg.ALL; |
USE mblite.core_Pkg.ALL; |
USE mblite.std_Pkg.ALL; |
library mblite; |
use mblite.config_Pkg.all; |
use mblite.core_Pkg.all; |
use mblite.std_Pkg.all; |
|
ENTITY testbench IS |
END testbench; |
entity testbench is |
end testbench; |
|
ARCHITECTURE arch OF testbench IS |
architecture arch of testbench is |
|
COMPONENT mblite_soc IS PORT |
component mblite_soc is port |
( |
sys_clk_i : in STD_LOGIC := 'X'; |
dbg_dmem_o_we_o : out STD_LOGIC; |
dbg_dmem_o_ena_o : out STD_LOGIC; |
sys_rst_i : in STD_LOGIC := 'X'; |
sys_ena_i : in STD_LOGIC := 'X'; |
sys_int_i : in STD_LOGIC := 'X'; |
dbg_dmem_o_adr_o : out STD_LOGIC_VECTOR(31 downto 0); |
dbg_dmem_o_dat_o : out STD_LOGIC_VECTOR(31 downto 0); |
dbg_dmem_o_sel_o : out STD_LOGIC_VECTOR( 3 downto 0) |
sys_clk_i : in std_logic := 'x'; |
dbg_dmem_o_we_o : out std_logic; |
dbg_dmem_o_ena_o : out std_logic; |
sys_rst_i : in std_logic := 'x'; |
sys_ena_i : in std_logic := 'x'; |
sys_int_i : in std_logic := 'x'; |
dbg_dmem_o_adr_o : out std_logic_vector(31 downto 0); |
dbg_dmem_o_dat_o : out std_logic_vector(31 downto 0); |
dbg_dmem_o_sel_o : out std_logic_vector( 3 downto 0) |
); |
END COMPONENT; |
end component; |
|
SIGNAL sys_clk_i : std_logic := '0'; |
SIGNAL sys_int_i : std_logic := '0'; |
SIGNAL sys_rst_i : std_logic := '0'; |
SIGNAL sys_ena_i : std_logic := '1'; |
signal sys_clk_i : std_logic := '0'; |
signal sys_int_i : std_logic := '0'; |
signal sys_rst_i : std_logic := '0'; |
signal sys_ena_i : std_logic := '1'; |
|
SIGNAL dmem_o : dmem_out_type; |
signal dmem_o : dmem_out_type; |
|
CONSTANT std_out_adr : std_logic_vector(CFG_DMEM_SIZE - 1 DOWNTO 0) := X"FFFFFFC0"; |
BEGIN |
constant std_out_adr : std_logic_vector(CFG_DMEM_SIZE - 1 downto 0) := X"FFFFFFC0"; |
begin |
|
sys_clk_i <= NOT sys_clk_i AFTER 10000 ps; |
sys_rst_i <= '1' AFTER 0 ps, '0' AFTER 150000 ps; |
sys_int_i <= '1' AFTER 500000000 ps, '0' after 500040000 ps; |
sys_clk_i <= not sys_clk_i after 10000 ps; |
sys_rst_i <= '1' after 0 ps, '0' after 150000 ps; |
sys_int_i <= '1' after 500000000 ps, '0' after 500040000 ps; |
|
soc : mblite_soc PORT MAP |
soc : mblite_soc port map |
( |
sys_clk_i => sys_clk_i, |
dbg_dmem_o_we_o => dmem_o.we_o, |
69,45 → 69,45
dbg_dmem_o_sel_o => dmem_o.sel_o |
); |
|
timeout: PROCESS(sys_clk_i) |
BEGIN |
IF NOW = 10 ms THEN |
REPORT "TIMEOUT" SEVERITY FAILURE; |
END IF; |
END PROCESS; |
timeout: process(sys_clk_i) |
begin |
if NOW = 10 ms then |
report "TIMEOUT" severity FAILURE; |
end if; |
end process; |
|
-- Character device |
stdio: PROCESS(sys_clk_i) |
VARIABLE s : line; |
VARIABLE byte : std_logic_vector(7 DOWNTO 0); |
VARIABLE char : character; |
BEGIN |
stdio: process(sys_clk_i) |
variable s : line; |
variable byte : std_logic_vector(7 downto 0); |
variable char : character; |
begin |
|
IF rising_edge(sys_clk_i) THEN |
IF (NOT sys_rst_i AND dmem_o.ena_o AND compare(dmem_o.adr_o, std_out_adr)) = '1' THEN |
IF dmem_o.we_o = '1' THEN |
if rising_edge(sys_clk_i) then |
if (not sys_rst_i and dmem_o.ena_o and compare(dmem_o.adr_o, std_out_adr)) = '1' then |
if dmem_o.we_o = '1' then |
-- WRITE STDOUT |
CASE dmem_o.sel_o IS |
WHEN "0001" => byte := dmem_o.dat_o( 7 DOWNTO 0); |
WHEN "0010" => byte := dmem_o.dat_o(15 DOWNTO 8); |
WHEN "0100" => byte := dmem_o.dat_o(23 DOWNTO 16); |
WHEN "1000" => byte := dmem_o.dat_o(31 DOWNTO 24); |
WHEN OTHERS => NULL; |
END CASE; |
case dmem_o.sel_o is |
when "0001" => byte := dmem_o.dat_o( 7 downto 0); |
when "0010" => byte := dmem_o.dat_o(15 downto 8); |
when "0100" => byte := dmem_o.dat_o(23 downto 16); |
when "1000" => byte := dmem_o.dat_o(31 downto 24); |
when others => null; |
end case; |
char := character'val(my_conv_integer(byte)); |
IF byte = X"0D" THEN |
if byte = X"0D" then |
-- Ignore character 13 |
ELSIF byte = X"0A" THEN |
elsif byte = X"0A" then |
-- Writeline on character 10 (newline) |
writeline(output, s); |
ELSE |
else |
-- Write to buffer |
write(s, char); |
END IF; |
END IF; |
END IF; |
END IF; |
end if; |
end if; |
end if; |
end if; |
|
END PROCESS; |
end process; |
|
END arch; |
end arch; |
/core_syn/mblite_soc.vhd
11,76 → 11,76
-- |
---------------------------------------------------------------------------------------------- |
|
LIBRARY ieee; |
USE ieee.std_logic_1164.ALL; |
USE ieee.std_logic_unsigned.ALL; |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
|
LIBRARY mblite; |
USE mblite.config_Pkg.ALL; |
USE mblite.core_Pkg.ALL; |
USE mblite.std_Pkg.ALL; |
library mblite; |
use mblite.config_Pkg.all; |
use mblite.core_Pkg.all; |
use mblite.std_Pkg.all; |
|
ENTITY mblite_soc IS PORT |
entity mblite_soc is port |
( |
sys_clk_i : IN std_logic; |
dbg_dmem_o_we_o : OUT std_logic; |
dbg_dmem_o_ena_o : OUT std_logic; |
sys_rst_i : IN std_logic; |
sys_ena_i : IN std_logic; |
sys_int_i : IN std_logic; |
dbg_dmem_o_adr_o : OUT std_logic_vector (31 DOWNTO 0); |
dbg_dmem_o_dat_o : OUT std_logic_vector (31 DOWNTO 0); |
dbg_dmem_o_sel_o : OUT std_logic_vector ( 3 DOWNTO 0) |
sys_clk_i : in std_logic; |
dbg_dmem_o_we_o : out std_logic; |
dbg_dmem_o_ena_o : out std_logic; |
sys_rst_i : in std_logic; |
sys_ena_i : in std_logic; |
sys_int_i : in std_logic; |
dbg_dmem_o_adr_o : out std_logic_vector (31 downto 0); |
dbg_dmem_o_dat_o : out std_logic_vector (31 downto 0); |
dbg_dmem_o_sel_o : out std_logic_vector ( 3 downto 0) |
); |
END mblite_soc; |
end mblite_soc; |
|
ARCHITECTURE arch OF mblite_soc IS |
architecture arch of mblite_soc is |
|
COMPONENT sram_init IS GENERIC |
component sram_init is generic |
( |
WIDTH : integer; |
SIZE : integer |
); |
PORT |
port |
( |
dat_o : OUT std_logic_vector(WIDTH - 1 DOWNTO 0); |
dat_i : IN std_logic_vector(WIDTH - 1 DOWNTO 0); |
adr_i : IN std_logic_vector(SIZE - 1 DOWNTO 0); |
wre_i : IN std_logic; |
ena_i : IN std_logic; |
clk_i : IN std_logic |
dat_o : out std_logic_vector(WIDTH - 1 downto 0); |
dat_i : in std_logic_vector(WIDTH - 1 downto 0); |
adr_i : in std_logic_vector(SIZE - 1 downto 0); |
wre_i : in std_logic; |
ena_i : in std_logic; |
clk_i : in std_logic |
); |
END COMPONENT; |
end component; |
|
COMPONENT sram_4en_init IS GENERIC |
component sram_4en_init is generic |
( |
WIDTH : integer; |
SIZE : integer |
); |
PORT |
port |
( |
dat_o : OUT std_logic_vector(WIDTH - 1 DOWNTO 0); |
dat_i : IN std_logic_vector(WIDTH - 1 DOWNTO 0); |
adr_i : IN std_logic_vector(SIZE - 1 DOWNTO 0); |
wre_i : IN std_logic_vector(3 DOWNTO 0); |
ena_i : IN std_logic; |
clk_i : IN std_logic |
dat_o : out std_logic_vector(WIDTH - 1 downto 0); |
dat_i : in std_logic_vector(WIDTH - 1 downto 0); |
adr_i : in std_logic_vector(SIZE - 1 downto 0); |
wre_i : in std_logic_vector(3 downto 0); |
ena_i : in std_logic; |
clk_i : in std_logic |
); |
END COMPONENT; |
end component; |
|
SIGNAL dmem_o : dmem_out_type; |
SIGNAL imem_o : imem_out_type; |
SIGNAL dmem_i : dmem_in_type; |
SIGNAL imem_i : imem_in_type; |
signal dmem_o : dmem_out_type; |
signal imem_o : imem_out_type; |
signal dmem_i : dmem_in_type; |
signal imem_i : imem_in_type; |
|
SIGNAL mem_enable : std_logic; |
SIGNAL sel_o : std_logic_vector(3 DOWNTO 0); |
signal mem_enable : std_logic; |
signal sel_o : std_logic_vector(3 downto 0); |
|
CONSTANT std_out_adr : std_logic_vector(CFG_DMEM_SIZE - 1 DOWNTO 0) := X"FFFFFFC0"; |
CONSTANT rom_size : integer := 13; |
CONSTANT ram_size : integer := 13; |
constant std_out_adr : std_logic_vector(CFG_DMEM_SIZE - 1 downto 0) := X"FFFFFFC0"; |
constant rom_size : integer := 13; |
constant ram_size : integer := 13; |
|
BEGIN |
begin |
|
dbg_dmem_o_we_o <= dmem_o.we_o; |
dbg_dmem_o_ena_o <= dmem_o.ena_o; |
88,34 → 88,34
dbg_dmem_o_dat_o <= dmem_o.dat_o; |
dbg_dmem_o_sel_o <= dmem_o.sel_o; |
|
imem : sram GENERIC MAP |
imem : sram generic map |
( |
WIDTH => CFG_IMEM_WIDTH, |
SIZE => rom_size - 2 |
) |
PORT MAP |
port map |
( |
dat_o => imem_i.dat_i, |
dat_i => "00000000000000000000000000000000", |
adr_i => imem_o.adr_o(rom_size - 1 DOWNTO 2), |
adr_i => imem_o.adr_o(rom_size - 1 downto 2), |
wre_i => '0', |
ena_i => imem_o.ena_o, |
clk_i => sys_clk_i |
); |
|
mem_enable <= NOT sys_rst_i AND dmem_o.ena_o AND NOT compare(dmem_o.adr_o, std_out_adr); |
sel_o <= dmem_o.sel_o WHEN dmem_o.we_o = '1' ELSE (OTHERS => '0'); |
mem_enable <= not sys_rst_i and dmem_o.ena_o and not compare(dmem_o.adr_o, std_out_adr); |
sel_o <= dmem_o.sel_o when dmem_o.we_o = '1' else (others => '0'); |
|
dmem : sram_4en GENERIC MAP |
dmem : sram_4en generic map |
( |
WIDTH => CFG_DMEM_WIDTH, |
SIZE => ram_size - 2 |
) |
PORT MAP |
port map |
( |
dat_o => dmem_i.dat_i, |
dat_i => dmem_o.dat_o, |
adr_i => dmem_o.adr_o(ram_size - 1 DOWNTO 2), |
adr_i => dmem_o.adr_o(ram_size - 1 downto 2), |
wre_i => sel_o, |
ena_i => mem_enable, |
clk_i => sys_clk_i |
123,7 → 123,7
|
dmem_i.ena_i <= sys_ena_i; |
|
core0 : core PORT MAP |
core0 : core port map |
( |
imem_o => imem_o, |
dmem_o => dmem_o, |
133,4 → 133,4
rst_i => sys_rst_i, |
clk_i => sys_clk_i |
); |
END arch; |
end arch; |
/core_syn/sram_init.vhd
11,32 → 11,32
-- |
---------------------------------------------------------------------------------------------- |
|
LIBRARY ieee; |
USE ieee.std_logic_1164.ALL; |
USE ieee.std_logic_unsigned.ALL; |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
|
LIBRARY mblite; |
USE mblite.std_Pkg.ALL; |
library mblite; |
use mblite.std_Pkg.all; |
|
ENTITY sram_init IS GENERIC |
entity sram_init is generic |
( |
WIDTH : integer := 32; |
SIZE : integer := 11 |
); |
PORT |
port |
( |
dat_o : OUT std_logic_vector(WIDTH - 1 DOWNTO 0); |
dat_i : IN std_logic_vector(WIDTH - 1 DOWNTO 0); |
adr_i : IN std_logic_vector(SIZE - 1 DOWNTO 0); |
wre_i : IN std_logic; |
ena_i : IN std_logic; |
clk_i : IN std_logic |
dat_o : out std_logic_vector(WIDTH - 1 downto 0); |
dat_i : in std_logic_vector(WIDTH - 1 downto 0); |
adr_i : in std_logic_vector(SIZE - 1 downto 0); |
wre_i : in std_logic; |
ena_i : in std_logic; |
clk_i : in std_logic |
); |
END sram_init; |
end sram_init; |
|
ARCHITECTURE arch OF sram_init IS |
TYPE ram_type IS array (0 TO 2 ** SIZE - 1) OF std_logic_vector(WIDTH - 1 DOWNTO 0); |
SIGNAL ram : ram_type := ( |
architecture arch of sram_init is |
type ram_type is array (0 to 2 ** SIZE - 1) of std_logic_vector(WIDTH - 1 downto 0); |
signal ram : ram_type := ( |
X"B8080050",X"00000000",X"B8080728",X"00000000",X"B8080738",X"00000000",X"00000000",X"00000000", |
X"B8080730",X"00000000",X"00000000",X"00000000",X"00000000",X"00000000",X"00000000",X"00000000", |
X"00000000",X"00000000",X"00000000",X"00000000",X"31A01028",X"30400F18",X"B0000000",X"30209038", |
294,16 → 294,16
X"00000000",X"00000000",X"00000000",X"00000000",X"00000000",X"00000000",X"00000000",X"00000000", |
X"00000000",X"00000000",X"00000000",X"00000000",X"00000000",X"00000000",X"00000000",X"00000000"); |
|
BEGIN |
PROCESS(clk_i) |
BEGIN |
IF rising_edge(clk_i) THEN |
IF notx(adr_i) AND ena_i = '1' THEN |
IF wre_i = '1' THEN |
begin |
process(clk_i) |
begin |
if rising_edge(clk_i) then |
if notx(adr_i) and ena_i = '1' then |
if wre_i = '1' then |
ram(my_conv_integer(adr_i)) <= dat_i; |
END IF; |
end if; |
dat_o <= ram(my_conv_integer(adr_i)); |
END IF; |
END IF; |
END PROCESS; |
END arch; |
end if; |
end if; |
end process; |
end arch; |
/core_syn/config_Pkg.vhd
11,52 → 11,52
-- |
---------------------------------------------------------------------------------------------- |
|
LIBRARY ieee; |
USE ieee.std_logic_1164.ALL; |
USE ieee.std_logic_unsigned.ALL; |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
|
PACKAGE config_Pkg IS |
package config_Pkg is |
|
---------------------------------------------------------------------------------------------- |
-- CORE PARAMETERS |
---------------------------------------------------------------------------------------------- |
-- Implement external interrupt |
CONSTANT CFG_INTERRUPT : boolean := true; -- Disable or enable external interrupt [0,1] |
constant CFG_INTERRUPT : boolean := true; -- Disable or enable external interrupt [0,1] |
|
-- Implement hardware multiplier |
CONSTANT CFG_USE_HW_MUL : boolean := false; -- Disable or enable multiplier [0,1] |
constant CFG_USE_HW_MUL : boolean := false; -- Disable or enable multiplier [0,1] |
|
-- Implement hardware barrel shifter |
CONSTANT CFG_USE_BARREL : boolean := false; -- Disable or enable barrel shifter [0,1] |
constant CFG_USE_BARREL : boolean := false; -- Disable or enable barrel shifter [0,1] |
|
-- Debug mode |
CONSTANT CFG_DEBUG : boolean := false; -- Resets some extra registers for better readability |
constant CFG_DEBUG : boolean := false; -- Resets some extra registers for better readability |
-- and enables feedback (report) [0,1] |
-- Set CFG_DEBUG to zero to obtain best performance. |
|
-- Memory parameters |
CONSTANT CFG_DMEM_SIZE : positive := 32; -- Data memory bus size in 2LOG # elements |
CONSTANT CFG_IMEM_SIZE : positive := 16; -- Instruction memory bus size in 2LOG # elements |
CONSTANT CFG_BYTE_ORDER : boolean := true; -- Switch between MSB (1, default) and LSB (0) byte order policy |
constant CFG_DMEM_SIZE : positive := 32; -- Data memory bus size in 2LOG # elements |
constant CFG_IMEM_SIZE : positive := 16; -- Instruction memory bus size in 2LOG # elements |
constant CFG_BYTE_ORDER : boolean := true; -- Switch between MSB (1, default) and LSB (0) byte order policy |
|
-- Register parameters |
CONSTANT CFG_REG_FORCE_ZERO : boolean := true; -- Force data to zero if register address is zero [0,1] |
CONSTANT CFG_REG_FWD_WB : boolean := true; -- Forward writeback to loosen register memory requirements [0,1] |
CONSTANT CFG_MEM_FWD_WB : boolean := true; -- Forward memory result in stead of introducing stalls [0,1] |
constant CFG_REG_FORCE_ZERO : boolean := true; -- Force data to zero if register address is zero [0,1] |
constant CFG_REG_FWD_WRB : boolean := true; -- Forward writeback to loosen register memory requirements [0,1] |
constant CFG_MEM_FWD_WRB : boolean := true; -- Forward memory result in stead of introducing stalls [0,1] |
|
---------------------------------------------------------------------------------------------- |
-- CONSTANTS (currently not configurable / not tested) |
---------------------------------------------------------------------------------------------- |
CONSTANT CFG_DMEM_WIDTH : positive := 32; -- Data memory width in bits |
CONSTANT CFG_IMEM_WIDTH : positive := 32; -- Instruction memory width in bits |
CONSTANT CFG_GPRF_SIZE : positive := 5; -- General Purpose Register File Size in 2LOG # elements |
constant CFG_DMEM_WIDTH : positive := 32; -- Data memory width in bits |
constant CFG_IMEM_WIDTH : positive := 32; -- Instruction memory width in bits |
constant CFG_GPRF_SIZE : positive := 5; -- General Purpose Register File Size in 2LOG # elements |
|
---------------------------------------------------------------------------------------------- |
-- BUS PARAMETERS |
---------------------------------------------------------------------------------------------- |
|
TYPE memory_map_type IS ARRAY(natural RANGE <>) OF std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0); |
CONSTANT CFG_NUM_SLAVES : positive := 2; |
CONSTANT CFG_MEMORY_MAP : memory_map_type(0 TO CFG_NUM_SLAVES) := (X"00000000", X"00FFFFFF", X"FFFFFFFF"); |
type memory_map_type is array(natural range <>) of std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0); |
constant CFG_NUM_SLAVES : positive := 2; |
constant CFG_MEMORY_MAP : memory_map_type(0 to CFG_NUM_SLAVES) := (X"00000000", X"00FFFFFF", X"FFFFFFFF"); |
|
END config_Pkg; |
/core_syn/sram_4en_init.vhd
13,32 → 13,32
-- |
---------------------------------------------------------------------------------------------- |
|
LIBRARY ieee; |
USE ieee.std_logic_1164.ALL; |
USE ieee.std_logic_unsigned.ALL; |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
|
LIBRARY mblite; |
USE mblite.std_Pkg.ALL; |
library mblite; |
use mblite.std_Pkg.all; |
|
ENTITY sram_4en_init IS GENERIC |
entity sram_4en_init is generic |
( |
WIDTH : integer := 32; |
SIZE : integer := 11 |
); |
PORT |
port |
( |
dat_o : OUT std_logic_vector(WIDTH - 1 DOWNTO 0); |
dat_i : IN std_logic_vector(WIDTH - 1 DOWNTO 0); |
adr_i : IN std_logic_vector(SIZE - 1 DOWNTO 0); |
wre_i : IN std_logic_vector(3 DOWNTO 0); |
ena_i : IN std_logic; |
clk_i : IN std_logic |
dat_o : out std_logic_vector(WIDTH - 1 downto 0); |
dat_i : in std_logic_vector(WIDTH - 1 downto 0); |
adr_i : in std_logic_vector(SIZE - 1 downto 0); |
wre_i : in std_logic_vector(3 downto 0); |
ena_i : in std_logic; |
clk_i : in std_logic |
); |
END sram_4en_init; |
end sram_4en_init; |
|
ARCHITECTURE arch OF sram_4en_init IS |
TYPE ram_type IS array (0 TO 2 ** SIZE - 1) OF std_logic_vector(WIDTH - 1 DOWNTO 0); |
SIGNAL ram : ram_type := ( |
architecture arch of sram_4en_init is |
type ram_type is array (0 to 2 ** size - 1) of std_logic_vector(WIDTH - 1 downto 0); |
signal ram : ram_type := ( |
X"B8080050",X"00000000",X"B8080728",X"00000000",X"B8080738",X"00000000",X"00000000",X"00000000", |
X"B8080730",X"00000000",X"00000000",X"00000000",X"00000000",X"00000000",X"00000000",X"00000000", |
X"00000000",X"00000000",X"00000000",X"00000000",X"31A01028",X"30400F18",X"B0000000",X"30209038", |
296,32 → 296,32
X"00000000",X"00000000",X"00000000",X"00000000",X"00000000",X"00000000",X"00000000",X"00000000", |
X"00000000",X"00000000",X"00000000",X"00000000",X"00000000",X"00000000",X"00000000",X"00000000"); |
|
SIGNAL di0, di1, di2, di3 : std_logic_vector(WIDTH/4 - 1 DOWNTO 0); |
BEGIN |
signal di0, di1, di2, di3 : std_logic_vector(WIDTH/4 - 1 downto 0); |
begin |
process(wre_i, dat_i, adr_i) |
begin |
if wre_i(0) = '1' then |
di0 <= dat_i(WIDTH/4 - 1 DOWNTO 0); |
di0 <= dat_i(WIDTH/4 - 1 downto 0); |
else |
di0 <= ram(my_conv_integer(adr_i))(WIDTH/4 - 1 DOWNTO 0); |
di0 <= ram(my_conv_integer(adr_i))(WIDTH/4 - 1 downto 0); |
end if; |
|
if wre_i(1) = '1' then |
di1 <= dat_i(WIDTH/2 - 1 DOWNTO WIDTH/4); |
di1 <= dat_i(WIDTH/2 - 1 downto WIDTH/4); |
else |
di1 <= ram(my_conv_integer(adr_i))(WIDTH/2 - 1 DOWNTO WIDTH/4); |
di1 <= ram(my_conv_integer(adr_i))(WIDTH/2 - 1 downto WIDTH/4); |
end if; |
|
if wre_i(2) = '1' then |
di2 <= dat_i(3*WIDTH/4 - 1 DOWNTO WIDTH/2); |
di2 <= dat_i(3*WIDTH/4 - 1 downto WIDTH/2); |
else |
di2 <= ram(my_conv_integer(adr_i))(3*WIDTH/4 - 1 DOWNTO WIDTH/2); |
di2 <= ram(my_conv_integer(adr_i))(3*WIDTH/4 - 1 downto WIDTH/2); |
end if; |
|
if wre_i(3) = '1' then |
di3 <= dat_i(WIDTH-1 DOWNTO 3*WIDTH/4); |
di3 <= dat_i(WIDTH-1 downto 3*WIDTH/4); |
else |
di3 <= ram(my_conv_integer(adr_i))(WIDTH-1 DOWNTO 3*WIDTH/4); |
di3 <= ram(my_conv_integer(adr_i))(WIDTH-1 downto 3*WIDTH/4); |
end if; |
end process; |
|
334,4 → 334,4
dat_o <= ram(my_conv_integer(adr_i)); |
end if; |
end process; |
END arch; |
end arch; |
/core_decoder_wb/testbench.vhd
12,69 → 12,69
-- |
---------------------------------------------------------------------------------------------- |
|
LIBRARY ieee; |
USE ieee.std_logic_1164.ALL; |
USE ieee.std_logic_unsigned.ALL; |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
|
LIBRARY mblite; |
USE mblite.config_Pkg.ALL; |
USE mblite.core_Pkg.ALL; |
USE mblite.std_Pkg.ALL; |
library mblite; |
use mblite.config_Pkg.all; |
use mblite.core_Pkg.all; |
use mblite.std_Pkg.all; |
|
ENTITY testbench IS |
END testbench; |
entity testbench is |
end testbench; |
|
ARCHITECTURE arch OF testbench IS |
architecture arch of testbench is |
|
COMPONENT wb_stdio IS PORT |
component wb_stdio is port |
( |
wb_o : OUT wb_slv_out_type; |
wb_i : IN wb_slv_in_type |
wb_o : out wb_slv_out_type; |
wb_i : in wb_slv_in_type |
); |
END COMPONENT; |
end component; |
|
SIGNAL dmem_o : dmem_out_type; |
SIGNAL dmem_i : dmem_in_type; |
SIGNAL imem_o : imem_out_type; |
SIGNAL imem_i : imem_in_type; |
SIGNAL s_dmem_o : dmem_out_array_type(CFG_NUM_SLAVES - 1 DOWNTO 0); |
SIGNAL s_dmem_i : dmem_in_array_type(CFG_NUM_SLAVES - 1 DOWNTO 0); |
signal dmem_o : dmem_out_type; |
signal dmem_i : dmem_in_type; |
signal imem_o : imem_out_type; |
signal imem_i : imem_in_type; |
signal s_dmem_o : dmem_out_array_type(CFG_NUM_SLAVES - 1 downto 0); |
signal s_dmem_i : dmem_in_array_type(CFG_NUM_SLAVES - 1 downto 0); |
|
SIGNAL m_wb_i : wb_mst_in_type; |
SIGNAL m_wb_o : wb_mst_out_type; |
SIGNAL s_wb_i : wb_slv_in_type; |
SIGNAL s_wb_o : wb_slv_out_type; |
signal m_wb_i : wb_mst_in_type; |
signal m_wb_o : wb_mst_out_type; |
signal s_wb_i : wb_slv_in_type; |
signal s_wb_o : wb_slv_out_type; |
|
SIGNAL sys_clk_i : std_logic := '0'; |
SIGNAL sys_int_i : std_logic; |
SIGNAL sys_rst_i : std_logic; |
signal sys_clk_i : std_logic := '0'; |
signal sys_int_i : std_logic; |
signal sys_rst_i : std_logic; |
|
CONSTANT rom_size : integer := 16; |
CONSTANT ram_size : integer := 16; |
constant rom_size : integer := 16; |
constant ram_size : integer := 16; |
|
SIGNAL sel_o : std_logic_vector(3 DOWNTO 0); |
SIGNAL ena_o : std_logic; |
signal sel_o : std_logic_vector(3 downto 0); |
signal ena_o : std_logic; |
|
BEGIN |
begin |
|
sys_clk_i <= NOT sys_clk_i AFTER 10000 ps; |
sys_rst_i <= '1' AFTER 0 ps, '0' AFTER 150000 ps; |
sys_int_i <= '1' AFTER 500000000 ps, '0' after 500040000 ps; |
sys_clk_i <= not sys_clk_i after 10000 ps; |
sys_rst_i <= '1' after 0 ps, '0' after 150000 ps; |
sys_int_i <= '1' after 500000000 ps, '0' after 500040000 ps; |
|
-- Warning: an infinite loop like while(1) {} triggers this timeout too! |
-- disable this feature when a premature finish occur. |
timeout: PROCESS(sys_clk_i) |
BEGIN |
IF NOW = 10 ms THEN |
REPORT "TIMEOUT" SEVERITY FAILURE; |
END IF; |
timeout: process(sys_clk_i) |
begin |
if NOW = 10 ms then |
report "TIMEOUT" severity FAILURE; |
end if; |
-- BREAK ON EXIT (0xB8000000) |
IF compare(imem_i.dat_i, "10111000000000000000000000000000") = '1' THEN |
if compare(imem_i.dat_i, "10111000000000000000000000000000") = '1' then |
-- Make sure the simulator finishes when an error is encountered. |
-- For modelsim: see menu Simulate -> Runtime options -> Assertions |
REPORT "FINISHED" SEVERITY FAILURE; |
END IF; |
END PROCESS; |
report "FINISHED" severity FAILURE; |
end if; |
end process; |
|
s_wb_i.clk_i <= sys_clk_i; |
s_wb_i.rst_i <= sys_rst_i; |
91,13 → 91,13
m_wb_i.ack_i <= s_wb_o.ack_o; |
m_wb_i.int_i <= s_wb_o.int_o; |
|
stdio : wb_stdio PORT MAP |
stdio : wb_stdio port map |
( |
wb_i => s_wb_i, |
wb_o => s_wb_o |
); |
|
wb_adapter : core_wb_adapter PORT MAP |
wb_adapter : core_wb_adapter port map |
( |
dmem_i => s_dmem_i(1), |
wb_o => m_wb_o, |
106,29 → 106,29
); |
|
s_dmem_i(0).ena_i <= '1'; |
sel_o <= s_dmem_o(0).sel_o WHEN s_dmem_o(0).we_o = '1' ELSE (OTHERS => '0'); |
ena_o <= NOT sys_rst_i AND s_dmem_o(0).ena_o; |
sel_o <= s_dmem_o(0).sel_o when s_dmem_o(0).we_o = '1' else (others => '0'); |
ena_o <= not sys_rst_i and s_dmem_o(0).ena_o; |
|
dmem : sram_4en GENERIC MAP |
dmem : sram_4en generic map |
( |
WIDTH => CFG_DMEM_WIDTH, |
SIZE => ram_size - 2 |
SIZE => ram_size - 2 |
) |
PORT MAP |
port map |
( |
dat_o => s_dmem_i(0).dat_i, |
dat_i => s_dmem_o(0).dat_o, |
adr_i => s_dmem_o(0).adr_o(ram_size - 1 DOWNTO 2), |
adr_i => s_dmem_o(0).adr_o(ram_size - 1 downto 2), |
wre_i => sel_o, |
ena_i => ena_o, |
clk_i => sys_clk_i |
); |
|
decoder : core_address_decoder GENERIC MAP |
decoder : core_address_decoder generic map |
( |
G_NUM_SLAVES => CFG_NUM_SLAVES |
) |
PORT MAP |
port map |
( |
m_dmem_i => dmem_i, |
s_dmem_o => s_dmem_o, |
137,22 → 137,22
clk_i => sys_clk_i |
); |
|
imem : sram GENERIC MAP |
imem : sram generic map |
( |
WIDTH => CFG_IMEM_WIDTH, |
SIZE => rom_size - 2 |
SIZE => rom_size - 2 |
) |
PORT MAP |
port map |
( |
dat_o => imem_i.dat_i, |
dat_i => "00000000000000000000000000000000", |
adr_i => imem_o.adr_o(rom_size - 1 DOWNTO 2), |
adr_i => imem_o.adr_o(rom_size - 1 downto 2), |
wre_i => '0', |
ena_i => imem_o.ena_o, |
clk_i => sys_clk_i |
); |
|
core0 : core PORT MAP |
core0 : core port map |
( |
imem_o => imem_o, |
dmem_o => dmem_o, |
163,4 → 163,4
clk_i => sys_clk_i |
); |
|
END arch; |
end arch; |
/core_decoder_wb/config_Pkg.vhd
11,52 → 11,52
-- |
---------------------------------------------------------------------------------------------- |
|
LIBRARY ieee; |
USE ieee.std_logic_1164.ALL; |
USE ieee.std_logic_unsigned.ALL; |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
|
PACKAGE config_Pkg IS |
package config_Pkg is |
|
---------------------------------------------------------------------------------------------- |
-- CORE PARAMETERS |
---------------------------------------------------------------------------------------------- |
-- Implement external interrupt |
CONSTANT CFG_INTERRUPT : boolean := true; -- Disable or enable external interrupt [0,1] |
constant CFG_INTERRUPT : boolean := true; -- Disable or enable external interrupt [0,1] |
|
-- Implement hardware multiplier |
CONSTANT CFG_USE_HW_MUL : boolean := true; -- Disable or enable multiplier [0,1] |
constant CFG_USE_HW_MUL : boolean := true; -- Disable or enable multiplier [0,1] |
|
-- Implement hardware barrel shifter |
CONSTANT CFG_USE_BARREL : boolean := true; -- Disable or enable barrel shifter [0,1] |
constant CFG_USE_BARREL : boolean := true; -- Disable or enable barrel shifter [0,1] |
|
-- Debug mode |
CONSTANT CFG_DEBUG : boolean := true; -- Resets some extra registers for better readability |
constant CFG_DEBUG : boolean := true; -- Resets some extra registers for better readability |
-- and enables feedback (report) [0,1] |
-- Set CFG_DEBUG to zero to obtain best performance. |
|
-- Memory parameters |
CONSTANT CFG_DMEM_SIZE : positive := 32; -- Data memory bus size in 2LOG # elements |
CONSTANT CFG_IMEM_SIZE : positive := 16; -- Instruction memory bus size in 2LOG # elements |
CONSTANT CFG_BYTE_ORDER : boolean := true; -- Switch between MSB (1, default) and LSB (0) byte order policy |
constant CFG_DMEM_SIZE : positive := 32; -- Data memory bus size in 2LOG # elements |
constant CFG_IMEM_SIZE : positive := 16; -- Instruction memory bus size in 2LOG # elements |
constant CFG_BYTE_ORDER : boolean := true; -- Switch between MSB (1, default) and LSB (0) byte order policy |
|
-- Register parameters |
CONSTANT CFG_REG_FORCE_ZERO : boolean := true; -- Force data to zero if register address is zero [0,1] |
CONSTANT CFG_REG_FWD_WB : boolean := true; -- Forward writeback to loosen register memory requirements [0,1] |
CONSTANT CFG_MEM_FWD_WB : boolean := true; -- Forward memory result in stead of introducing stalls [0,1] |
constant CFG_REG_FORCE_ZERO : boolean := true; -- Force data to zero if register address is zero [0,1] |
constant CFG_REG_FWD_WRB : boolean := true; -- Forward writeback to loosen register memory requirements [0,1] |
constant CFG_MEM_FWD_WRB : boolean := true; -- Forward memory result in stead of introducing stalls [0,1] |
|
---------------------------------------------------------------------------------------------- |
-- CONSTANTS (currently not configurable / not tested) |
---------------------------------------------------------------------------------------------- |
CONSTANT CFG_DMEM_WIDTH : positive := 32; -- Data memory width in bits |
CONSTANT CFG_IMEM_WIDTH : positive := 32; -- Instruction memory width in bits |
CONSTANT CFG_GPRF_SIZE : positive := 5; -- General Purpose Register File Size in 2LOG # elements |
constant CFG_DMEM_WIDTH : positive := 32; -- Data memory width in bits |
constant CFG_IMEM_WIDTH : positive := 32; -- Instruction memory width in bits |
constant CFG_GPRF_SIZE : positive := 5; -- General Purpose Register File Size in 2LOG # elements |
|
---------------------------------------------------------------------------------------------- |
-- BUS PARAMETERS |
---------------------------------------------------------------------------------------------- |
|
TYPE memory_map_type IS ARRAY(natural RANGE <>) OF std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0); |
CONSTANT CFG_NUM_SLAVES : positive := 2; |
CONSTANT CFG_MEMORY_MAP : memory_map_type(0 TO CFG_NUM_SLAVES) := (X"00000000", X"00FFFFFF", X"FFFFFFFF"); |
type memory_map_type is array(natural range <>) of std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0); |
constant CFG_NUM_SLAVES : positive := 2; |
constant CFG_MEMORY_MAP : memory_map_type(0 to CFG_NUM_SLAVES) := (X"00000000", X"00FFFFFF", X"FFFFFFFF"); |
|
END config_Pkg; |
end config_Pkg; |
/core_decoder_wb/wb_stdio.vhd
11,84 → 11,84
-- |
---------------------------------------------------------------------------------------------- |
|
LIBRARY ieee; |
USE ieee.std_logic_1164.ALL; |
USE ieee.std_logic_unsigned.ALL; |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
|
LIBRARY mblite; |
USE mblite.config_Pkg.ALL; |
USE mblite.core_Pkg.ALL; |
USE mblite.std_Pkg.ALL; |
library mblite; |
use mblite.config_Pkg.all; |
use mblite.core_Pkg.all; |
use mblite.std_Pkg.all; |
|
USE std.textio.ALL; |
use std.textio.all; |
|
ENTITY wb_stdio IS PORT |
entity wb_stdio is port |
( |
wb_o : OUT wb_slv_out_type; |
wb_i : IN wb_slv_in_type |
wb_o : out wb_slv_out_type; |
wb_i : in wb_slv_in_type |
); |
END wb_stdio; |
end wb_stdio; |
|
ARCHITECTURE arch OF wb_stdio IS |
CONSTANT ack_assert_delay : TIME := 2 ns; |
CONSTANT ack_deassert_delay : TIME := 2 ns; |
SIGNAL ack : std_logic; |
SIGNAL chr_dat : std_logic_vector(31 DOWNTO 0); |
SIGNAL chr_cnt : natural := 0; |
BEGIN |
architecture arch of wb_stdio is |
constant ack_assert_delay : TIME := 2 ns; |
constant ack_deassert_delay : TIME := 2 ns; |
signal ack : std_logic; |
signal chr_dat : std_logic_vector(31 downto 0); |
signal chr_cnt : natural := 0; |
begin |
wb_o.int_o <= '0'; |
wb_o.dat_o <= chr_dat; |
-- Character device |
stdio: PROCESS(wb_i.clk_i) |
VARIABLE s : line; |
VARIABLE byte : std_logic_vector(7 DOWNTO 0); |
VARIABLE char : character; |
BEGIN |
IF rising_edge(wb_i.clk_i) THEN |
IF (wb_i.stb_i AND wb_i.cyc_i) = '1' THEN |
IF wb_i.we_i = '1' AND ack = '0' THEN |
stdio: process(wb_i.clk_i) |
variable s : line; |
variable byte : std_logic_vector(7 downto 0); |
variable char : character; |
begin |
if rising_edge(wb_i.clk_i) then |
if (wb_i.stb_i and wb_i.cyc_i) = '1' then |
if wb_i.we_i = '1' and ack = '0' then |
-- WRITE STDOUT |
wb_o.ack_o <= '1' AFTER ack_assert_delay; |
wb_o.ack_o <= '1' after ack_assert_delay; |
ack <= '1'; |
CASE wb_i.sel_i IS |
WHEN "0001" => byte := wb_i.dat_i( 7 DOWNTO 0); |
WHEN "0010" => byte := wb_i.dat_i(15 DOWNTO 8); |
WHEN "0100" => byte := wb_i.dat_i(23 DOWNTO 16); |
WHEN "1000" => byte := wb_i.dat_i(31 DOWNTO 24); |
WHEN OTHERS => NULL; |
END CASE; |
case wb_i.sel_i is |
when "0001" => byte := wb_i.dat_i( 7 downto 0); |
when "0010" => byte := wb_i.dat_i(15 downto 8); |
when "0100" => byte := wb_i.dat_i(23 downto 16); |
when "1000" => byte := wb_i.dat_i(31 downto 24); |
when others => null; |
end case; |
char := character'val(my_conv_integer(byte)); |
IF byte = X"0D" THEN |
if byte = X"0D" then |
-- Ignore character 13 |
ELSIF byte = X"0A" THEN |
elsif byte = X"0A" then |
-- Writeline on character 10 (newline) |
writeline(output, s); |
ELSE |
else |
-- Write to buffer |
write(s, char); |
END IF; |
ELSIF ack = '0' THEN |
end if; |
elsif ack = '0' then |
-- READ stdout |
ack <= '1'; |
wb_o.ack_o <= '1' AFTER ack_assert_delay; |
IF chr_cnt = 0 THEN |
wb_o.ack_o <= '1' after ack_assert_delay; |
if chr_cnt = 0 then |
chr_cnt <= 1; |
chr_dat <= X"4C4C4C4C"; |
ELSIF chr_cnt = 1 THEN |
elsif chr_cnt = 1 then |
chr_cnt <= 2; |
chr_dat <= X"4D4D4D4D"; |
ELSIF chr_cnt = 2 THEN |
elsif chr_cnt = 2 then |
chr_cnt <= 3; |
chr_dat <= X"4E4E4E4E"; |
ELSIF chr_cnt = 3 THEN |
elsif chr_cnt = 3 then |
chr_cnt <= 0; |
chr_dat <= X"0A0A0A0A"; |
END IF; |
END IF; |
ELSE |
end if; |
end if; |
else |
ack <= '0'; |
wb_o.ack_o <= '0' AFTER ack_deassert_delay; |
END IF; |
END IF; |
END PROCESS; |
END arch; |
wb_o.ack_o <= '0' after ack_deassert_delay; |
end if; |
end if; |
end process; |
end arch; |
/core/testbench.vhd
12,157 → 12,157
-- |
---------------------------------------------------------------------------------------------- |
|
LIBRARY ieee; |
USE ieee.std_logic_1164.ALL; |
USE ieee.std_logic_unsigned.ALL; |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
|
LIBRARY std; |
USE std.textio.ALL; |
library std; |
use std.textio.all; |
|
LIBRARY mblite; |
USE mblite.config_Pkg.ALL; |
USE mblite.core_Pkg.ALL; |
USE mblite.std_Pkg.ALL; |
library mblite; |
use mblite.config_Pkg.all; |
use mblite.core_Pkg.all; |
use mblite.std_Pkg.all; |
|
ENTITY testbench IS |
END testbench; |
entity testbench is |
end testbench; |
|
ARCHITECTURE arch OF testbench IS |
architecture arch of testbench is |
|
SIGNAL dmem_o : dmem_out_type; |
SIGNAL imem_o : imem_out_type; |
SIGNAL dmem_i : dmem_in_type; |
SIGNAL imem_i : imem_in_type; |
signal dmem_o : dmem_out_type; |
signal imem_o : imem_out_type; |
signal dmem_i : dmem_in_type; |
signal imem_i : imem_in_type; |
|
SIGNAL sys_clk_i : std_logic := '0'; |
SIGNAL sys_int_i : std_logic := '0'; |
SIGNAL sys_rst_i : std_logic := '0'; |
SIGNAL sys_ena_i : std_logic := '1'; |
signal sys_clk_i : std_logic := '0'; |
signal sys_int_i : std_logic := '0'; |
signal sys_rst_i : std_logic := '0'; |
signal sys_ena_i : std_logic := '1'; |
|
CONSTANT std_out_adr : std_logic_vector(CFG_DMEM_SIZE - 1 DOWNTO 0) := X"FFFFFFC0"; |
CONSTANT rom_size : integer := 16; |
CONSTANT ram_size : integer := 16; |
constant std_out_adr : std_logic_vector(CFG_DMEM_SIZE - 1 downto 0) := X"FFFFFFC0"; |
constant rom_size : integer := 16; |
constant ram_size : integer := 16; |
|
SIGNAL mem_enable : std_logic; |
SIGNAL chr_enable : std_logic; |
SIGNAL chr_read : std_logic; |
SIGNAL sel_o : std_logic_vector(3 DOWNTO 0); |
SIGNAL mem_dat : std_logic_vector(31 DOWNTO 0); |
SIGNAL chr_dat : std_logic_vector(31 DOWNTO 0); |
SIGNAL chr_cnt : integer := 0; |
signal mem_enable : std_logic; |
signal chr_enable : std_logic; |
signal chr_read : std_logic; |
signal sel_o : std_logic_vector(3 downto 0); |
signal mem_dat : std_logic_vector(31 downto 0); |
signal chr_dat : std_logic_vector(31 downto 0); |
signal chr_cnt : integer := 0; |
|
BEGIN |
|
sys_clk_i <= NOT sys_clk_i AFTER 10000 ps; |
sys_rst_i <= '1' AFTER 0 ps, '0' AFTER 150000 ps; |
sys_int_i <= '1' AFTER 500000000 ps, '0' after 500040000 ps; |
sys_clk_i <= not sys_clk_i after 10000 ps; |
sys_rst_i <= '1' after 0 ps, '0' after 150000 ps; |
sys_int_i <= '1' after 500000000 ps, '0' after 500040000 ps; |
|
|
dmem_i.ena_i <= sys_ena_i; |
sel_o <= dmem_o.sel_o WHEN dmem_o.we_o = '1' ELSE (OTHERS => '0'); |
sel_o <= dmem_o.sel_o when dmem_o.we_o = '1' else (others => '0'); |
|
mem_enable <= NOT sys_rst_i AND dmem_o.ena_o AND NOT compare(dmem_o.adr_o, std_out_adr); |
chr_enable <= NOT sys_rst_i AND dmem_o.ena_o AND compare(dmem_o.adr_o, std_out_adr); |
mem_enable <= not sys_rst_i and dmem_o.ena_o and not compare(dmem_o.adr_o, std_out_adr); |
chr_enable <= not sys_rst_i and dmem_o.ena_o and compare(dmem_o.adr_o, std_out_adr); |
|
dmem_i.dat_i <= chr_dat WHEN chr_read = '1' ELSE mem_dat; |
dmem_i.dat_i <= chr_dat when chr_read = '1' else mem_dat; |
|
-- Character device |
stdio: PROCESS(sys_clk_i) |
VARIABLE s : line; |
VARIABLE byte : std_logic_vector(7 DOWNTO 0); |
VARIABLE char : character; |
BEGIN |
IF rising_edge(sys_clk_i) THEN |
IF chr_enable = '1' THEN |
IF dmem_o.we_o = '1' THEN |
stdio: process(sys_clk_i) |
variable s : line; |
variable byte : std_logic_vector(7 downto 0); |
variable char : character; |
begin |
if rising_edge(sys_clk_i) then |
if chr_enable = '1' then |
if dmem_o.we_o = '1' then |
-- WRITE STDOUT |
CASE dmem_o.sel_o IS |
WHEN "0001" => byte := dmem_o.dat_o( 7 DOWNTO 0); |
WHEN "0010" => byte := dmem_o.dat_o(15 DOWNTO 8); |
WHEN "0100" => byte := dmem_o.dat_o(23 DOWNTO 16); |
WHEN "1000" => byte := dmem_o.dat_o(31 DOWNTO 24); |
WHEN OTHERS => NULL; |
END CASE; |
case dmem_o.sel_o is |
when "0001" => byte := dmem_o.dat_o( 7 downto 0); |
when "0010" => byte := dmem_o.dat_o(15 downto 8); |
when "0100" => byte := dmem_o.dat_o(23 downto 16); |
when "1000" => byte := dmem_o.dat_o(31 downto 24); |
when others => null; |
end case; |
char := character'val(my_conv_integer(byte)); |
IF byte = X"0D" THEN |
if byte = X"0D" then |
-- Ignore character 13 |
ELSIF byte = X"0A" THEN |
elsif byte = X"0A" then |
-- Writeline on character 10 (newline) |
writeline(output, s); |
ELSE |
else |
-- Write to buffer |
write(s, char); |
END IF; |
end if; |
chr_read <= '0'; |
ELSE |
else |
chr_read <= '1'; |
IF chr_cnt = 0 THEN |
if chr_cnt = 0 then |
chr_cnt <= 1; |
chr_dat <= X"4C4C4C4C"; |
ELSIF chr_cnt = 1 THEN |
elsif chr_cnt = 1 then |
chr_cnt <= 2; |
chr_dat <= X"4D4D4D4D"; |
ELSIF chr_cnt = 2 THEN |
elsif chr_cnt = 2 then |
chr_cnt <= 3; |
chr_dat <= X"4E4E4E4E"; |
ELSIF chr_cnt = 3 THEN |
elsif chr_cnt = 3 then |
chr_cnt <= 0; |
chr_dat <= X"0A0A0A0A"; |
END IF; |
END IF; |
ELSE |
end if; |
end if; |
else |
chr_read <= '0'; |
END IF; |
END IF; |
end if; |
end if; |
|
END PROCESS; |
end process; |
|
-- Warning: an infinite loop like while(1) {} triggers this timeout too! |
-- disable this feature when a premature finish occur. |
timeout: PROCESS(sys_clk_i) |
BEGIN |
IF NOW = 10 ms THEN |
REPORT "TIMEOUT" SEVERITY FAILURE; |
END IF; |
timeout: process(sys_clk_i) |
begin |
if now = 10 ms then |
report "TIMEOUT" severity FAILURE; |
end if; |
-- BREAK ON EXIT (0xB8000000) |
IF compare(imem_i.dat_i, "10111000000000000000000000000000") = '1' THEN |
if compare(imem_i.dat_i, "10111000000000000000000000000000") = '1' then |
-- Make sure the simulator finishes when an error is encountered. |
-- For modelsim: see menu Simulate -> Runtime options -> Assertions |
REPORT "FINISHED" SEVERITY FAILURE; |
END IF; |
END PROCESS; |
report "FINISHED" severity FAILURE; |
end if; |
end process; |
|
imem : sram GENERIC MAP |
imem : sram generic map |
( |
WIDTH => CFG_IMEM_WIDTH, |
SIZE => rom_size - 2 |
) |
PORT MAP |
port map |
( |
dat_o => imem_i.dat_i, |
dat_i => "00000000000000000000000000000000", |
adr_i => imem_o.adr_o(rom_size - 1 DOWNTO 2), |
adr_i => imem_o.adr_o(rom_size - 1 downto 2), |
wre_i => '0', |
ena_i => imem_o.ena_o, |
clk_i => sys_clk_i |
); |
|
dmem : sram_4en GENERIC MAP |
dmem : sram_4en generic map |
( |
WIDTH => CFG_DMEM_WIDTH, |
SIZE => ram_size - 2 |
) |
PORT MAP |
port map |
( |
dat_o => mem_dat, |
dat_i => dmem_o.dat_o, |
adr_i => dmem_o.adr_o(ram_size - 1 DOWNTO 2), |
adr_i => dmem_o.adr_o(ram_size - 1 downto 2), |
wre_i => sel_o, |
ena_i => mem_enable, |
clk_i => sys_clk_i |
); |
|
core0 : core PORT MAP |
core0 : core port map |
( |
imem_o => imem_o, |
dmem_o => dmem_o, |
173,7 → 173,7
clk_i => sys_clk_i |
); |
|
END arch; |
end arch; |
|
---------------------------------------------------------------------------------------------- |
-- USE CONFIGURATIONS INSTEAD OF GENERICS TO IMPLEMENT - FOR EXAMPLE - DIFFERENT MEMORIES. |
180,10 → 180,10
-- CONFIGURATIONS CAN HIERARCHICALLY INVOKE OTHER CONFIGURATIONS TO REDUCE THE SIZE OF THE |
-- CONFIGURATION DECLARATION |
---------------------------------------------------------------------------------------------- |
CONFIGURATION tb_conf_example OF testbench IS |
FOR arch |
FOR ALL: sram_4en |
USE ENTITY mblite.sram_4en(arch); |
END FOR; |
END FOR; |
END tb_conf_example; |
configuration tb_conf_example of testbench is |
for arch |
for all: sram_4en |
use entity mblite.sram_4en(arch); |
end for; |
end for; |
end tb_conf_example; |
/core/config_Pkg.vhd
11,52 → 11,52
-- |
---------------------------------------------------------------------------------------------- |
|
LIBRARY ieee; |
USE ieee.std_logic_1164.ALL; |
USE ieee.std_logic_unsigned.ALL; |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
|
PACKAGE config_Pkg IS |
package config_Pkg is |
|
---------------------------------------------------------------------------------------------- |
-- CORE PARAMETERS |
---------------------------------------------------------------------------------------------- |
-- Implement external interrupt |
CONSTANT CFG_INTERRUPT : boolean := true; -- Disable or enable external interrupt [0,1] |
constant CFG_INTERRUPT : boolean := true; -- Disable or enable external interrupt [0,1] |
|
-- Implement hardware multiplier |
CONSTANT CFG_USE_HW_MUL : boolean := true; -- Disable or enable multiplier [0,1] |
constant CFG_USE_HW_MUL : boolean := true; -- Disable or enable multiplier [0,1] |
|
-- Implement hardware barrel shifter |
CONSTANT CFG_USE_BARREL : boolean := true; -- Disable or enable barrel shifter [0,1] |
constant CFG_USE_BARREL : boolean := true; -- Disable or enable barrel shifter [0,1] |
|
-- Debug mode |
CONSTANT CFG_DEBUG : boolean := true; -- Resets some extra registers for better readability |
constant CFG_DEBUG : boolean := true; -- Resets some extra registers for better readability |
-- and enables feedback (report) [0,1] |
-- Set CFG_DEBUG to zero to obtain best performance. |
|
-- Memory parameters |
CONSTANT CFG_DMEM_SIZE : positive := 32; -- Data memory bus size in 2LOG # elements |
CONSTANT CFG_IMEM_SIZE : positive := 16; -- Instruction memory bus size in 2LOG # elements |
CONSTANT CFG_BYTE_ORDER : boolean := true; -- Switch between MSB (1, default) and LSB (0) byte order policy |
constant CFG_DMEM_SIZE : positive := 32; -- Data memory bus size in 2LOG # elements |
constant CFG_IMEM_SIZE : positive := 16; -- Instruction memory bus size in 2LOG # elements |
constant CFG_BYTE_ORDER : boolean := true; -- Switch between MSB (1, default) and LSB (0) byte order policy |
|
-- Register parameters |
CONSTANT CFG_REG_FORCE_ZERO : boolean := true; -- Force data to zero if register address is zero [0,1] |
CONSTANT CFG_REG_FWD_WB : boolean := true; -- Forward writeback to loosen register memory requirements [0,1] |
CONSTANT CFG_MEM_FWD_WB : boolean := true; -- Forward memory result in stead of introducing stalls [0,1] |
constant CFG_REG_FORCE_ZERO : boolean := true; -- Force data to zero if register address is zero [0,1] |
constant CFG_REG_FWD_WRB : boolean := true; -- Forward writeback to loosen register memory requirements [0,1] |
constant CFG_MEM_FWD_WRB : boolean := true; -- Forward memory result in stead of introducing stalls [0,1] |
|
---------------------------------------------------------------------------------------------- |
-- CONSTANTS (currently not configurable / not tested) |
---------------------------------------------------------------------------------------------- |
CONSTANT CFG_DMEM_WIDTH : positive := 32; -- Data memory width in bits |
CONSTANT CFG_IMEM_WIDTH : positive := 32; -- Instruction memory width in bits |
CONSTANT CFG_GPRF_SIZE : positive := 5; -- General Purpose Register File Size in 2LOG # elements |
constant CFG_DMEM_WIDTH : positive := 32; -- Data memory width in bits |
constant CFG_IMEM_WIDTH : positive := 32; -- Instruction memory width in bits |
constant CFG_GPRF_SIZE : positive := 5; -- General Purpose Register File Size in 2LOG # elements |
|
---------------------------------------------------------------------------------------------- |
-- BUS PARAMETERS |
---------------------------------------------------------------------------------------------- |
|
TYPE memory_map_type IS ARRAY(natural RANGE <>) OF std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0); |
CONSTANT CFG_NUM_SLAVES : positive := 2; |
CONSTANT CFG_MEMORY_MAP : memory_map_type(0 TO CFG_NUM_SLAVES) := (X"00000000", X"00FFFFFF", X"FFFFFFFF"); |
type memory_map_type is array(natural range <>) of std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0); |
constant CFG_NUM_SLAVES : positive := 2; |
constant CFG_MEMORY_MAP : memory_map_type(0 to CFG_NUM_SLAVES) := (X"00000000", X"00FFFFFF", X"FFFFFFFF"); |
|
END config_Pkg; |
end config_Pkg; |
/core_decoder/testbench.vhd
12,67 → 12,67
-- |
---------------------------------------------------------------------------------------------- |
|
LIBRARY ieee; |
USE ieee.std_logic_1164.ALL; |
USE ieee.std_logic_unsigned.ALL; |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
|
LIBRARY mblite; |
USE mblite.config_Pkg.ALL; |
USE mblite.core_Pkg.ALL; |
USE mblite.std_Pkg.ALL; |
library mblite; |
use mblite.config_Pkg.all; |
use mblite.core_Pkg.all; |
use mblite.std_Pkg.all; |
|
ENTITY testbench IS |
END testbench; |
entity testbench is |
end testbench; |
|
ARCHITECTURE arch OF testbench IS |
architecture arch of testbench is |
|
COMPONENT mblite_stdio IS PORT |
component mblite_stdio is port |
( |
dmem_i : OUT dmem_in_type; |
dmem_o : IN dmem_out_type; |
clk_i : IN std_logic |
dmem_i : out dmem_in_type; |
dmem_o : in dmem_out_type; |
clk_i : in std_logic |
); |
END COMPONENT; |
end component; |
|
SIGNAL dmem_o : dmem_out_type; |
SIGNAL dmem_i : dmem_in_type; |
SIGNAL imem_o : imem_out_type; |
SIGNAL imem_i : imem_in_type; |
SIGNAL s_dmem_o : dmem_out_array_type(CFG_NUM_SLAVES - 1 DOWNTO 0); |
SIGNAL s_dmem_i : dmem_in_array_type(CFG_NUM_SLAVES - 1 DOWNTO 0); |
signal dmem_o : dmem_out_type; |
signal dmem_i : dmem_in_type; |
signal imem_o : imem_out_type; |
signal imem_i : imem_in_type; |
signal s_dmem_o : dmem_out_array_type(CFG_NUM_SLAVES - 1 downto 0); |
signal s_dmem_i : dmem_in_array_type(CFG_NUM_SLAVES - 1 downto 0); |
|
SIGNAL sys_clk_i : std_logic := '0'; |
SIGNAL sys_int_i : std_logic; |
SIGNAL sys_rst_i : std_logic; |
signal sys_clk_i : std_logic := '0'; |
signal sys_int_i : std_logic; |
signal sys_rst_i : std_logic; |
|
CONSTANT rom_size : integer := 16; |
CONSTANT ram_size : integer := 16; |
constant rom_size : integer := 16; |
constant ram_size : integer := 16; |
|
SIGNAL sel_o : std_logic_vector(3 DOWNTO 0); |
SIGNAL ena_o : std_logic; |
signal sel_o : std_logic_vector(3 downto 0); |
signal ena_o : std_logic; |
|
BEGIN |
|
sys_clk_i <= NOT sys_clk_i AFTER 10000 ps; |
sys_rst_i <= '1' AFTER 0 ps, '0' AFTER 150000 ps; |
sys_int_i <= '1' AFTER 500000000 ps, '0' after 500040000 ps; |
sys_clk_i <= not sys_clk_i after 10000 ps; |
sys_rst_i <= '1' after 0 ps, '0' after 150000 ps; |
sys_int_i <= '1' after 500000000 ps, '0' after 500040000 ps; |
|
-- Warning: an infinite loop like while(1) {} triggers this timeout too! |
-- disable this feature when a premature finish occur. |
timeout: PROCESS(sys_clk_i) |
BEGIN |
IF NOW = 10 ms THEN |
REPORT "TIMEOUT" SEVERITY FAILURE; |
END IF; |
timeout: process(sys_clk_i) |
begin |
if NOW = 10 ms then |
report "TIMEOUT" severity FAILURE; |
end if; |
-- BREAK ON EXIT (0xB8000000) |
IF compare(imem_i.dat_i, "10111000000000000000000000000000") = '1' THEN |
if compare(imem_i.dat_i, "10111000000000000000000000000000") = '1' then |
-- Make sure the simulator finishes when an error is encountered. |
-- For modelsim: see menu Simulate -> Runtime options -> Assertions |
REPORT "FINISHED" SEVERITY FAILURE; |
END IF; |
END PROCESS; |
report "FINISHED" severity FAILURE; |
end if; |
end process; |
|
stdio : mblite_stdio PORT MAP |
stdio : mblite_stdio port map |
( |
dmem_i => s_dmem_i(1), |
dmem_o => s_dmem_o(1), |
80,29 → 80,29
); |
|
s_dmem_i(0).ena_i <= '1'; |
sel_o <= s_dmem_o(0).sel_o WHEN s_dmem_o(0).we_o = '1' ELSE (OTHERS => '0'); |
ena_o <= NOT sys_rst_i AND s_dmem_o(0).ena_o; |
sel_o <= s_dmem_o(0).sel_o when s_dmem_o(0).we_o = '1' else (others => '0'); |
ena_o <= not sys_rst_i and s_dmem_o(0).ena_o; |
|
dmem : sram_4en GENERIC MAP |
dmem : sram_4en generic map |
( |
WIDTH => CFG_DMEM_WIDTH, |
SIZE => ram_size - 2 |
) |
PORT MAP |
port map |
( |
dat_o => s_dmem_i(0).dat_i, |
dat_i => s_dmem_o(0).dat_o, |
adr_i => s_dmem_o(0).adr_o(ram_size - 1 DOWNTO 2), |
adr_i => s_dmem_o(0).adr_o(ram_size - 1 downto 2), |
wre_i => sel_o, |
ena_i => ena_o, |
clk_i => sys_clk_i |
); |
|
decoder : core_address_decoder GENERIC MAP |
decoder : core_address_decoder generic map |
( |
G_NUM_SLAVES => CFG_NUM_SLAVES |
) |
PORT MAP |
port map |
( |
m_dmem_i => dmem_i, |
s_dmem_o => s_dmem_o, |
111,22 → 111,22
clk_i => sys_clk_i |
); |
|
imem : sram GENERIC MAP |
imem : sram generic map |
( |
WIDTH => CFG_IMEM_WIDTH, |
SIZE => rom_size - 2 |
) |
PORT MAP |
port map |
( |
dat_o => imem_i.dat_i, |
dat_i => "00000000000000000000000000000000", |
adr_i => imem_o.adr_o(rom_size - 1 DOWNTO 2), |
adr_i => imem_o.adr_o(rom_size - 1 downto 2), |
wre_i => '0', |
ena_i => imem_o.ena_o, |
clk_i => sys_clk_i |
); |
|
core0 : core PORT MAP |
core0 : core port map |
( |
imem_o => imem_o, |
dmem_o => dmem_o, |
137,4 → 137,4
clk_i => sys_clk_i |
); |
|
END arch; |
end arch; |
/core_decoder/config_Pkg.vhd
11,52 → 11,52
-- |
---------------------------------------------------------------------------------------------- |
|
LIBRARY ieee; |
USE ieee.std_logic_1164.ALL; |
USE ieee.std_logic_unsigned.ALL; |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
|
PACKAGE config_Pkg IS |
package config_Pkg is |
|
---------------------------------------------------------------------------------------------- |
-- CORE PARAMETERS |
---------------------------------------------------------------------------------------------- |
-- Implement external interrupt |
CONSTANT CFG_INTERRUPT : boolean := true; -- Disable or enable external interrupt [0,1] |
constant CFG_INTERRUPT : boolean := true; -- Disable or enable external interrupt [0,1] |
|
-- Implement hardware multiplier |
CONSTANT CFG_USE_HW_MUL : boolean := true; -- Disable or enable multiplier [0,1] |
constant CFG_USE_HW_MUL : boolean := true; -- Disable or enable multiplier [0,1] |
|
-- Implement hardware barrel shifter |
CONSTANT CFG_USE_BARREL : boolean := true; -- Disable or enable barrel shifter [0,1] |
constant CFG_USE_BARREL : boolean := true; -- Disable or enable barrel shifter [0,1] |
|
-- Debug mode |
CONSTANT CFG_DEBUG : boolean := true; -- Resets some extra registers for better readability |
constant CFG_DEBUG : boolean := true; -- Resets some extra registers for better readability |
-- and enables feedback (report) [0,1] |
-- Set CFG_DEBUG to zero to obtain best performance. |
|
-- Memory parameters |
CONSTANT CFG_DMEM_SIZE : positive := 32; -- Data memory bus size in 2LOG # elements |
CONSTANT CFG_IMEM_SIZE : positive := 16; -- Instruction memory bus size in 2LOG # elements |
CONSTANT CFG_BYTE_ORDER : boolean := true; -- Switch between MSB (1, default) and LSB (0) byte order policy |
constant CFG_DMEM_SIZE : positive := 32; -- Data memory bus size in 2LOG # elements |
constant CFG_IMEM_SIZE : positive := 16; -- Instruction memory bus size in 2LOG # elements |
constant CFG_BYTE_ORDER : boolean := true; -- Switch between MSB (1, default) and LSB (0) byte order policy |
|
-- Register parameters |
CONSTANT CFG_REG_FORCE_ZERO : boolean := true; -- Force data to zero if register address is zero [0,1] |
CONSTANT CFG_REG_FWD_WB : boolean := true; -- Forward writeback to loosen register memory requirements [0,1] |
CONSTANT CFG_MEM_FWD_WB : boolean := true; -- Forward memory result in stead of introducing stalls [0,1] |
constant CFG_REG_FORCE_ZERO : boolean := true; -- Force data to zero if register address is zero [0,1] |
constant CFG_REG_FWD_WRB : boolean := true; -- Forward writeback to loosen register memory requirements [0,1] |
constant CFG_MEM_FWD_WRB : boolean := true; -- Forward memory result in stead of introducing stalls [0,1] |
|
---------------------------------------------------------------------------------------------- |
-- CONSTANTS (currently not configurable / not tested) |
---------------------------------------------------------------------------------------------- |
CONSTANT CFG_DMEM_WIDTH : positive := 32; -- Data memory width in bits |
CONSTANT CFG_IMEM_WIDTH : positive := 32; -- Instruction memory width in bits |
CONSTANT CFG_GPRF_SIZE : positive := 5; -- General Purpose Register File Size in 2LOG # elements |
constant CFG_DMEM_WIDTH : positive := 32; -- Data memory width in bits |
constant CFG_IMEM_WIDTH : positive := 32; -- Instruction memory width in bits |
constant CFG_GPRF_SIZE : positive := 5; -- General Purpose Register File Size in 2LOG # elements |
|
---------------------------------------------------------------------------------------------- |
-- BUS PARAMETERS |
---------------------------------------------------------------------------------------------- |
|
TYPE memory_map_type IS ARRAY(natural RANGE <>) OF std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0); |
CONSTANT CFG_NUM_SLAVES : positive := 2; |
CONSTANT CFG_MEMORY_MAP : memory_map_type(0 TO CFG_NUM_SLAVES) := (X"00000000", X"00FFFFFF", X"FFFFFFFF"); |
type memory_map_type is array(natural range <>) of std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0); |
constant CFG_NUM_SLAVES : positive := 2; |
constant CFG_MEMORY_MAP : memory_map_type(0 to CFG_NUM_SLAVES) := (X"00000000", X"00FFFFFF", X"FFFFFFFF"); |
|
END config_Pkg; |
end config_Pkg; |
/core_decoder/mblite_stdio.vhd
11,58 → 11,58
-- |
---------------------------------------------------------------------------------------------- |
|
LIBRARY ieee; |
USE ieee.std_logic_1164.ALL; |
USE ieee.std_logic_unsigned.ALL; |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
|
LIBRARY mblite; |
USE mblite.config_Pkg.ALL; |
USE mblite.core_Pkg.ALL; |
USE mblite.std_Pkg.ALL; |
library mblite; |
use mblite.config_Pkg.all; |
use mblite.core_Pkg.all; |
use mblite.std_Pkg.all; |
|
USE std.textio.ALL; |
use std.textio.all; |
|
ENTITY mblite_stdio IS PORT |
entity mblite_stdio is port |
( |
dmem_i : OUT dmem_in_type; |
dmem_o : IN dmem_out_type; |
clk_i : IN std_logic |
dmem_i : out dmem_in_type; |
dmem_o : in dmem_out_type; |
clk_i : in std_logic |
); |
END mblite_stdio; |
end mblite_stdio; |
|
ARCHITECTURE arch OF mblite_stdio IS |
BEGIN |
architecture arch of mblite_stdio is |
begin |
-- Character device |
stdio: PROCESS(clk_i) |
VARIABLE s : line; |
VARIABLE byte : std_logic_vector(7 DOWNTO 0); |
VARIABLE char : character; |
BEGIN |
dmem_i.dat_i <= (OTHERS => '0'); |
stdio: process(clk_i) |
variable s : line; |
variable byte : std_logic_vector(7 downto 0); |
variable char : character; |
begin |
dmem_i.dat_i <= (others => '0'); |
dmem_i.ena_i <= '1'; |
IF rising_edge(clk_i) THEN |
IF dmem_o.ena_o = '1' THEN |
IF dmem_o.we_o = '1' THEN |
if rising_edge(clk_i) then |
if dmem_o.ena_o = '1' then |
if dmem_o.we_o = '1' then |
-- WRITE STDOUT |
CASE dmem_o.sel_o IS |
WHEN "0001" => byte := dmem_o.dat_o( 7 DOWNTO 0); |
WHEN "0010" => byte := dmem_o.dat_o(15 DOWNTO 8); |
WHEN "0100" => byte := dmem_o.dat_o(23 DOWNTO 16); |
WHEN "1000" => byte := dmem_o.dat_o(31 DOWNTO 24); |
WHEN OTHERS => NULL; |
END CASE; |
case dmem_o.sel_o is |
when "0001" => byte := dmem_o.dat_o( 7 downto 0); |
when "0010" => byte := dmem_o.dat_o(15 downto 8); |
when "0100" => byte := dmem_o.dat_o(23 downto 16); |
when "1000" => byte := dmem_o.dat_o(31 downto 24); |
when others => null; |
end case; |
char := character'val(my_conv_integer(byte)); |
IF byte = X"0D" THEN |
if byte = x"0d" then |
-- Ignore character 13 |
ELSIF byte = X"0A" THEN |
elsif byte = x"0a" then |
-- Writeline on character 10 (newline) |
writeline(output, s); |
ELSE |
else |
-- Write to buffer |
write(s, char); |
END IF; |
END IF; |
END IF; |
END IF; |
END PROCESS; |
END arch; |
end if; |
end if; |
end if; |
end if; |
end process; |
end arch; |