OpenCores
URL https://opencores.org/ocsvn/mblite/mblite/trunk

Subversion Repositories mblite

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 7 to Rev 8
    Reverse comparison

Rev 7 → Rev 8

/mblite/trunk/changelog.txt
1,3 → 1,5
[2010-03-30] Added utility sw/util/bin2vhd_32b.c
[2010-03-30] Added utility sw/util/bin2vhd_4x8b.c
[2010-03-31] Fixed the bug with BGT and BGE instruction
[2010-03-31] Fixed the bug with BGT and BGE instruction
[2010-03-31] Formatted code according to industry standards
[2010-04-01] Fixed the bug with Carry_Keep
/mblite/trunk/designs/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;
/mblite/trunk/designs/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;
/mblite/trunk/designs/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;
/mblite/trunk/designs/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;
/mblite/trunk/designs/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;
/mblite/trunk/designs/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;
/mblite/trunk/designs/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;
/mblite/trunk/designs/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;
/mblite/trunk/designs/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;
/mblite/trunk/designs/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;
/mblite/trunk/designs/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;
/mblite/trunk/designs/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;
/mblite/trunk/designs/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;
/mblite/trunk/designs/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;
/mblite/trunk/designs/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;
/mblite/trunk/hw/core/core_wb.vhd
12,16 → 12,16
--
----------------------------------------------------------------------------------------------
 
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 core_wb IS GENERIC
entity core_wb is generic
(
G_INTERRUPT : boolean := CFG_INTERRUPT;
G_USE_HW_MUL : boolean := CFG_USE_HW_MUL;
28,21 → 28,21
G_USE_BARREL : boolean := CFG_USE_BARREL;
G_DEBUG : boolean := CFG_DEBUG
);
PORT
port
(
imem_o : OUT imem_out_type;
wb_o : OUT wb_mst_out_type;
imem_i : IN imem_in_type;
wb_i : IN wb_mst_in_type
imem_o : out imem_out_type;
wb_o : out wb_mst_out_type;
imem_i : in imem_in_type;
wb_i : in wb_mst_in_type
);
END core_wb;
end core_wb;
 
ARCHITECTURE arch OF core_wb IS
SIGNAL dmem_i : dmem_in_type;
SIGNAL dmem_o : dmem_out_type;
BEGIN
architecture arch of core_wb is
signal dmem_i : dmem_in_type;
signal dmem_o : dmem_out_type;
begin
 
wb_adapter0 : core_wb_adapter PORT MAP
wb_adapter0 : core_wb_adapter port map
(
dmem_i => dmem_i,
wb_o => wb_o,
50,7 → 50,7
wb_i => wb_i
);
 
core0 : core GENERIC MAP
core0 : core generic map
(
G_INTERRUPT => G_INTERRUPT,
G_USE_HW_MUL => G_USE_HW_MUL,
57,7 → 57,7
G_USE_BARREL => G_USE_BARREL,
G_DEBUG => G_DEBUG
)
PORT MAP
port map
(
imem_o => imem_o,
dmem_o => dmem_o,
68,4 → 68,4
clk_i => wb_i.clk_i
);
 
END arch;
end arch;
/mblite/trunk/hw/core/core_wb_adapter.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.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 core_wb_adapter IS PORT
entity core_wb_adapter is port
(
dmem_i : OUT dmem_in_type;
wb_o : OUT wb_mst_out_type;
dmem_o : IN dmem_out_type;
wb_i : IN wb_mst_in_type
dmem_i : out dmem_in_type;
wb_o : out wb_mst_out_type;
dmem_o : in dmem_out_type;
wb_i : in wb_mst_in_type
);
END core_wb_adapter;
end core_wb_adapter;
 
ARCHITECTURE arch OF core_wb_adapter IS
architecture arch of core_wb_adapter is
 
SIGNAL r_cyc_o : std_logic;
SIGNAL rin_cyc_o : std_logic;
SIGNAL r_data, rin_data : std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0);
SIGNAL s_wait : std_logic;
signal r_cyc_o : std_logic;
signal rin_cyc_o : std_logic;
signal r_data, rin_data : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
signal s_wait : std_logic;
 
BEGIN
begin
 
-- Direct input-output connections
wb_o.adr_o <= dmem_o.adr_o;
47,52 → 47,52
dmem_i.dat_i <= wb_i.dat_i;
 
-- synchronous bus control connections
wb_o.cyc_o <= r_cyc_o OR wb_i.ack_i;
wb_o.cyc_o <= r_cyc_o or wb_i.ack_i;
wb_o.stb_o <= r_cyc_o;
 
-- asynchronous core enable connection
dmem_i.ena_i <= '0' WHEN (dmem_o.ena_o = '1' AND rin_cyc_o = '1') OR s_wait = '1' ELSE '1';
dmem_i.ena_i <= '0' when (dmem_o.ena_o = '1' and rin_cyc_o = '1') or s_wait = '1' else '1';
wb_o.dat_o <= rin_data;
 
-- logic for wishbone master
wb_adapter_comb: PROCESS(wb_i, dmem_o, r_cyc_o, r_data)
BEGIN
wb_adapter_comb: process(wb_i, dmem_o, r_cyc_o, r_data)
begin
 
IF wb_i.rst_i = '1' THEN
if wb_i.rst_i = '1' then
-- reset bus
rin_data <= r_data;
rin_cyc_o <= '0';
s_wait <= '0';
ELSIF r_cyc_o = '1' AND wb_i.ack_i = '1' THEN
elsif r_cyc_o = '1' and wb_i.ack_i = '1' then
-- terminate wishbone cycle
rin_data <= r_data;
rin_cyc_o <= '0';
s_wait <= '0';
ELSIF dmem_o.ena_o = '1' AND wb_i.ack_i = '1' THEN
elsif dmem_o.ena_o = '1' and wb_i.ack_i = '1' then
-- wishbone bus is occuppied
rin_data <= r_data;
rin_cyc_o <= '1';
s_wait <= '1';
ELSIF r_cyc_o = '0' AND dmem_o.ena_o = '1' AND wb_i.ack_i = '0' THEN
elsif r_cyc_o = '0' and dmem_o.ena_o = '1' and wb_i.ack_i = '0' then
-- start wishbone cycle
rin_data <= dmem_o.dat_o;
rin_cyc_o <= '1';
s_wait <= '0';
ELSE
else
-- maintain wishbone cycle
rin_data <= r_data;
rin_cyc_o <= r_cyc_o;
s_wait <= '0';
END IF;
end if;
 
END PROCESS;
end process;
 
wb_adapter_seq: PROCESS(wb_i.clk_i)
BEGIN
IF rising_edge(wb_i.clk_i) THEN
wb_adapter_seq: process(wb_i.clk_i)
begin
if rising_edge(wb_i.clk_i) then
r_cyc_o <= rin_cyc_o;
r_data <= rin_data;
END IF;
END PROCESS;
end if;
end process;
 
END arch;
end arch;
/mblite/trunk/hw/core/core_address_decoder.vhd
11,86 → 11,87
--
----------------------------------------------------------------------------------------------
 
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 core_address_decoder IS GENERIC
entity core_address_decoder is generic
(
G_NUM_SLAVES : positive := CFG_NUM_SLAVES;
G_MEMORY_MAP : memory_map_type := CFG_MEMORY_MAP
);
PORT
port
(
m_dmem_i : OUT dmem_in_type;
s_dmem_o : OUT dmem_out_array_type(G_NUM_SLAVES - 1 DOWNTO 0);
m_dmem_o : IN dmem_out_type;
s_dmem_i : IN dmem_in_array_type(G_NUM_SLAVES - 1 DOWNTO 0);
m_dmem_i : out dmem_in_type;
s_dmem_o : out dmem_out_array_type(G_NUM_SLAVES - 1 downto 0);
m_dmem_o : in dmem_out_type;
s_dmem_i : in dmem_in_array_type(G_NUM_SLAVES - 1 downto 0);
clk_i : std_logic
);
END core_address_decoder;
end core_address_decoder;
 
ARCHITECTURE arch OF core_address_decoder IS
architecture arch of core_address_decoder is
 
-- Decodes the address based on the memory map. Returns "1" if 0 or 1 slave is attached.
FUNCTION decode(adr : std_logic_vector) RETURN std_logic_vector IS
VARIABLE result : std_logic_vector(G_NUM_SLAVES - 1 DOWNTO 0);
BEGIN
result := (OTHERS => '1');
IF G_NUM_SLAVES > 1 AND notx(adr) THEN
FOR i IN G_NUM_SLAVES - 1 DOWNTO 0 LOOP
IF (adr >= G_MEMORY_MAP(i) AND adr < G_MEMORY_MAP(i+1)) THEN
function decode(adr : std_logic_vector) return std_logic_vector is
variable result : std_logic_vector(G_NUM_SLAVES - 1 downto 0);
begin
if G_NUM_SLAVES > 1 and notx(adr) then
for i in G_NUM_SLAVES - 1 downto 0 loop
if (adr >= G_MEMORY_MAP(i) and adr < G_MEMORY_MAP(i+1)) then
result(i) := '1';
ELSE
else
result(i) := '0';
END IF;
END LOOP;
END IF;
RETURN result;
END FUNCTION;
end if;
end loop;
else
result := (others => '1');
end if;
return result;
end function;
 
FUNCTION demux(dmem_i : dmem_in_array_type; ce, r_ce : std_logic_vector) RETURN dmem_in_type IS
VARIABLE dmem : dmem_in_type;
BEGIN
function demux(dmem_i : dmem_in_array_type; ce, r_ce : std_logic_vector) return dmem_in_type is
variable dmem : dmem_in_type;
begin
dmem := dmem_i(0);
IF notx(ce) THEN
FOR i IN G_NUM_SLAVES - 1 DOWNTO 0 LOOP
IF ce(i) = '1' THEN
if notx(ce) then
for i in G_NUM_SLAVES - 1 downto 0 loop
if ce(i) = '1' then
dmem.ena_i := dmem_i(i).ena_i;
END IF;
IF r_ce(i) = '1' THEN
end if;
if r_ce(i) = '1' then
dmem.dat_i := dmem_i(i).dat_i;
END IF;
END LOOP;
END IF;
RETURN dmem;
END FUNCTION;
end if;
end loop;
end if;
return dmem;
end function;
 
SIGNAL r_ce, ce : std_logic_vector(G_NUM_SLAVES - 1 DOWNTO 0) := (OTHERS => '1');
signal r_ce, ce : std_logic_vector(G_NUM_SLAVES - 1 downto 0) := (others => '1');
 
BEGIN
begin
 
ce <= decode(m_dmem_o.adr_o);
m_dmem_i <= demux(s_dmem_i, ce, r_ce);
 
CON: FOR i IN G_NUM_SLAVES-1 DOWNTO 0 GENERATE
BEGIN
CON: for i in G_NUM_SLAVES-1 downto 0 generate
begin
s_dmem_o(i).dat_o <= m_dmem_o.dat_o;
s_dmem_o(i).adr_o <= m_dmem_o.adr_o;
s_dmem_o(i).sel_o <= m_dmem_o.sel_o;
s_dmem_o(i).we_o <= m_dmem_o.we_o AND ce(i);
s_dmem_o(i).ena_o <= m_dmem_o.ena_o AND ce(i);
END GENERATE;
s_dmem_o(i).we_o <= m_dmem_o.we_o and ce(i);
s_dmem_o(i).ena_o <= m_dmem_o.ena_o and ce(i);
end generate;
 
PROCESS(clk_i)
BEGIN
IF rising_edge(clk_i) THEN
process(clk_i)
begin
if rising_edge(clk_i) then
r_ce <= ce;
END IF;
END PROCESS;
END arch;
end if;
end process;
end arch;
/mblite/trunk/hw/core/execute.vhd
14,244 → 14,244
--
----------------------------------------------------------------------------------------------
 
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 execute IS GENERIC
entity execute is generic
(
G_USE_HW_MUL : boolean := CFG_USE_HW_MUL;
G_USE_BARREL : boolean := CFG_USE_BARREL
);
PORT
port
(
exec_o : OUT execute_out_type;
exec_i : IN execute_in_type;
ena_i : IN std_logic;
rst_i : IN std_logic;
clk_i : IN std_logic
exec_o : out execute_out_type;
exec_i : in execute_in_type;
ena_i : in std_logic;
rst_i : in std_logic;
clk_i : in std_logic
);
END execute;
end execute;
 
ARCHITECTURE arch OF execute IS
architecture arch of execute is
 
TYPE execute_reg_type IS RECORD
carry : std_logic;
flush_ex : std_logic;
END RECORD;
type execute_reg_type is record
carry : std_logic;
flush_ex : std_logic;
end record;
 
SIGNAL r, rin : execute_out_type;
SIGNAL reg, regin : execute_reg_type;
signal r, rin : execute_out_type;
signal reg, regin : execute_reg_type;
 
BEGIN
begin
 
exec_o <= r;
 
execute_comb: PROCESS(exec_i,exec_i.fwd_mem,exec_i.ctrl_ex,
exec_i.ctrl_wb,exec_i.ctrl_mem,
execute_comb: process(exec_i,exec_i.fwd_mem,exec_i.ctrl_ex,
exec_i.ctrl_wrb,exec_i.ctrl_mem,
exec_i.ctrl_mem.transfer_size,
exec_i.ctrl_mem_wb,exec_i.fwd_dec,
exec_i.ctrl_mem_wrb,exec_i.fwd_dec,
r,r.ctrl_mem,r.ctrl_mem.transfer_size,
r.ctrl_wb,reg)
r.ctrl_wrb,reg)
 
VARIABLE v : execute_out_type;
VARIABLE v_reg : execute_reg_type;
variable v : execute_out_type;
variable v_reg : execute_reg_type;
 
VARIABLE alu_src_a : std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0);
VARIABLE alu_src_b : std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0);
VARIABLE carry : std_logic;
variable alu_src_a : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
variable alu_src_b : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
variable carry : std_logic;
 
VARIABLE result : std_logic_vector(CFG_DMEM_WIDTH DOWNTO 0);
VARIABLE result_add : std_logic_vector(CFG_DMEM_WIDTH DOWNTO 0);
VARIABLE zero : std_logic;
variable result : std_logic_vector(CFG_DMEM_WIDTH downto 0);
variable result_add : std_logic_vector(CFG_DMEM_WIDTH downto 0);
variable zero : std_logic;
 
VARIABLE dat_a, dat_b : std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0);
VARIABLE sel_dat_a, sel_dat_b, sel_dat_d : std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0);
VARIABLE mem_result : std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0);
variable dat_a, dat_b : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
variable sel_dat_a, sel_dat_b, sel_dat_d : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
variable mem_result : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
 
BEGIN
begin
 
v := r;
 
sel_dat_a := select_register_data(exec_i.dat_a, exec_i.reg_a, exec_i.fwd_dec_result, forward_condition(exec_i.fwd_dec.reg_write, exec_i.fwd_dec.reg_d, exec_i.reg_a));
sel_dat_b := select_register_data(exec_i.dat_b, exec_i.reg_b, exec_i.fwd_dec_result, forward_condition(exec_i.fwd_dec.reg_write, exec_i.fwd_dec.reg_d, exec_i.reg_b));
sel_dat_d := select_register_data(exec_i.dat_d, exec_i.ctrl_wb.reg_d, exec_i.fwd_dec_result, forward_condition(exec_i.fwd_dec.reg_write, exec_i.fwd_dec.reg_d, exec_i.ctrl_wb.reg_d));
sel_dat_d := select_register_data(exec_i.dat_d, exec_i.ctrl_wrb.reg_d, exec_i.fwd_dec_result, forward_condition(exec_i.fwd_dec.reg_write, exec_i.fwd_dec.reg_d, exec_i.ctrl_wrb.reg_d));
 
IF reg.flush_ex = '1' THEN
if reg.flush_ex = '1' then
v.ctrl_mem.mem_write := '0';
v.ctrl_mem.mem_read := '0';
v.ctrl_wb.reg_write := '0';
v.ctrl_wb.reg_d := (OTHERS => '0');
ELSE
v.ctrl_wrb.reg_write := '0';
v.ctrl_wrb.reg_d := (others => '0');
else
v.ctrl_mem := exec_i.ctrl_mem;
v.ctrl_wb := exec_i.ctrl_wb;
END IF;
v.ctrl_wrb := exec_i.ctrl_wrb;
end if;
 
IF exec_i.ctrl_mem_wb.mem_read = '1' THEN
mem_result := align_mem_load(exec_i.mem_result, exec_i.ctrl_mem_wb.transfer_size, exec_i.alu_result(1 DOWNTO 0));
ELSE
if exec_i.ctrl_mem_wrb.mem_read = '1' then
mem_result := align_mem_load(exec_i.mem_result, exec_i.ctrl_mem_wrb.transfer_size, exec_i.alu_result(1 downto 0));
else
mem_result := exec_i.alu_result;
END IF;
end if;
 
IF forward_condition(r.ctrl_wb.reg_write, r.ctrl_wb.reg_d, exec_i.reg_a) = '1' THEN
if forward_condition(r.ctrl_wrb.reg_write, r.ctrl_wrb.reg_d, exec_i.reg_a) = '1' then
-- Forward Execution Result to REG a
dat_a := r.alu_result;
ELSIF forward_condition(exec_i.fwd_mem.reg_write, exec_i.fwd_mem.reg_d, exec_i.reg_a) = '1' THEN
elsif forward_condition(exec_i.fwd_mem.reg_write, exec_i.fwd_mem.reg_d, exec_i.reg_a) = '1' then
-- Forward Memory Result to REG a
dat_a := mem_result;
ELSE
else
-- DEFAULT: value of REG a
dat_a := sel_dat_a;
END IF;
end if;
 
IF forward_condition(r.ctrl_wb.reg_write, r.ctrl_wb.reg_d, exec_i.reg_b) = '1' THEN
if forward_condition(r.ctrl_wrb.reg_write, r.ctrl_wrb.reg_d, exec_i.reg_b) = '1' then
-- Forward (latched) Execution Result to REG b
dat_b := r.alu_result;
ELSIF forward_condition(exec_i.fwd_mem.reg_write, exec_i.fwd_mem.reg_d, exec_i.reg_b) = '1' THEN
elsif forward_condition(exec_i.fwd_mem.reg_write, exec_i.fwd_mem.reg_d, exec_i.reg_b) = '1' then
-- Forward Memory Result to REG b
dat_b := mem_result;
ELSE
else
-- DEFAULT: value of REG b
dat_b := sel_dat_b;
END IF;
end if;
 
IF forward_condition(r.ctrl_wb.reg_write, r.ctrl_wb.reg_d, exec_i.ctrl_wb.reg_d) = '1' THEN
if forward_condition(r.ctrl_wrb.reg_write, r.ctrl_wrb.reg_d, exec_i.ctrl_wrb.reg_d) = '1' then
-- Forward Execution Result to REG d
v.dat_d := align_mem_store(r.alu_result, exec_i.ctrl_mem.transfer_size);
ELSIF forward_condition(exec_i.fwd_mem.reg_write, exec_i.fwd_mem.reg_d, exec_i.ctrl_wb.reg_d) = '1' THEN
elsif forward_condition(exec_i.fwd_mem.reg_write, exec_i.fwd_mem.reg_d, exec_i.ctrl_wrb.reg_d) = '1' then
-- Forward Memory Result to REG d
v.dat_d := align_mem_store(mem_result, exec_i.ctrl_mem.transfer_size);
ELSE
else
-- DEFAULT: value of REG d
v.dat_d := align_mem_store(sel_dat_d, exec_i.ctrl_mem.transfer_size);
END IF;
end if;
 
-- Set the first operand of the ALU
CASE exec_i.ctrl_ex.alu_src_a IS
WHEN ALU_SRC_PC => alu_src_a := sign_extend(exec_i.program_counter, '0', 32);
WHEN ALU_SRC_NOT_REGA => alu_src_a := NOT dat_a;
WHEN ALU_SRC_ZERO => alu_src_a := (OTHERS => '0');
WHEN OTHERS => alu_src_a := dat_a;
END CASE;
case exec_i.ctrl_ex.alu_src_a is
when ALU_SRC_PC => alu_src_a := sign_extend(exec_i.program_counter, '0', 32);
when ALU_SRC_NOT_REGA => alu_src_a := not dat_a;
when ALU_SRC_ZERO => alu_src_a := (others => '0');
when others => alu_src_a := dat_a;
end case;
 
-- Set the second operand of the ALU
CASE exec_i.ctrl_ex.alu_src_b IS
WHEN ALU_SRC_IMM => alu_src_b := exec_i.imm;
WHEN ALU_SRC_NOT_IMM => alu_src_b := NOT exec_i.imm;
WHEN ALU_SRC_NOT_REGB => alu_src_b := NOT dat_b;
WHEN OTHERS => alu_src_b := dat_b;
END CASE;
case exec_i.ctrl_ex.alu_src_b is
when ALU_SRC_IMM => alu_src_b := exec_i.imm;
when ALU_SRC_NOT_IMM => alu_src_b := not exec_i.imm;
when ALU_SRC_NOT_REGB => alu_src_b := not dat_b;
when others => alu_src_b := dat_b;
end case;
 
-- Determine value of carry in
CASE exec_i.ctrl_ex.carry IS
WHEN CARRY_ALU => carry := reg.carry;
WHEN CARRY_ONE => carry := '1';
WHEN CARRY_ARITH => carry := alu_src_a(CFG_DMEM_WIDTH - 1);
WHEN OTHERS => carry := '0';
END CASE;
case exec_i.ctrl_ex.carry is
when CARRY_ALU => carry := reg.carry;
when CARRY_ONE => carry := '1';
when CARRY_ARITH => carry := alu_src_a(CFG_DMEM_WIDTH - 1);
when others => carry := '0';
end case;
 
result_add := add(alu_src_a, alu_src_b, carry);
 
CASE exec_i.ctrl_ex.alu_op IS
WHEN ALU_ADD => result := result_add;
WHEN ALU_OR => result := '0' & (alu_src_a OR alu_src_b);
WHEN ALU_AND => result := '0' & (alu_src_a AND alu_src_b);
WHEN ALU_XOR => result := '0' & (alu_src_a XOR alu_src_b);
WHEN ALU_SHIFT => result := alu_src_a(0) & carry & alu_src_a(CFG_DMEM_WIDTH - 1 DOWNTO 1);
WHEN ALU_SEXT8 => result := '0' & sign_extend(alu_src_a(7 DOWNTO 0), alu_src_a(7), 32);
WHEN ALU_SEXT16 => result := '0' & sign_extend(alu_src_a(15 DOWNTO 0), alu_src_a(15), 32);
WHEN ALU_MUL =>
IF G_USE_HW_MUL = true THEN
case exec_i.ctrl_ex.alu_op is
when ALU_ADD => result := result_add;
when ALU_OR => result := '0' & (alu_src_a or alu_src_b);
when ALU_AND => result := '0' & (alu_src_a and alu_src_b);
when ALU_XOR => result := '0' & (alu_src_a xor alu_src_b);
when ALU_SHIFT => result := alu_src_a(0) & carry & alu_src_a(CFG_DMEM_WIDTH - 1 downto 1);
when ALU_SEXT8 => result := '0' & sign_extend(alu_src_a(7 downto 0), alu_src_a(7), 32);
when ALU_SEXT16 => result := '0' & sign_extend(alu_src_a(15 downto 0), alu_src_a(15), 32);
when ALU_MUL =>
if G_USE_HW_MUL = true then
result := '0' & multiply(alu_src_a, alu_src_b);
ELSE
result := (OTHERS => '0');
END IF;
WHEN ALU_BS =>
IF G_USE_BARREL = true THEN
result := '0' & shift(alu_src_a, alu_src_b(4 DOWNTO 0), exec_i.imm(10), exec_i.imm(9));
ELSE
result := (OTHERS => '0');
END IF;
WHEN OTHERS =>
result := (OTHERS => '0');
REPORT "Invalid ALU operation" SEVERITY FAILURE;
END CASE;
else
result := (others => '0');
end if;
when ALU_BS =>
if G_USE_BARREL = true then
result := '0' & shift(alu_src_a, alu_src_b(4 downto 0), exec_i.imm(10), exec_i.imm(9));
else
result := (others => '0');
end if;
when others =>
result := (others => '0');
report "Invalid ALU operation" severity FAILURE;
end case;
 
-- Set carry register
IF exec_i.ctrl_ex.carry_keep = CARRY_KEEP THEN
if exec_i.ctrl_ex.carry_keep = CARRY_KEEP then
v_reg.carry := reg.carry;
ELSE
else
v_reg.carry := result(CFG_DMEM_WIDTH);
END IF;
end if;
 
zero := is_zero(dat_a);
 
-- Overwrite branch condition
IF reg.flush_ex = '1' THEN
if reg.flush_ex = '1' then
v.branch := '0';
ELSE
else
-- Determine branch condition
CASE exec_i.ctrl_ex.branch_cond IS
WHEN BNC => v.branch := '1';
WHEN BEQ => v.branch := zero;
WHEN BNE => v.branch := NOT zero;
WHEN BLT => v.branch := dat_a(CFG_DMEM_WIDTH - 1);
WHEN BLE => v.branch := dat_a(CFG_DMEM_WIDTH - 1) OR zero;
WHEN BGT => v.branch := NOT (dat_a(CFG_DMEM_WIDTH - 1) OR zero);
WHEN BGE => v.branch := NOT dat_a(CFG_DMEM_WIDTH - 1);
WHEN OTHERS => v.branch := '0';
END CASE;
END IF;
case exec_i.ctrl_ex.branch_cond is
when BNC => v.branch := '1';
when BEQ => v.branch := zero;
when BNE => v.branch := not zero;
when BLT => v.branch := dat_a(CFG_DMEM_WIDTH - 1);
when BLE => v.branch := dat_a(CFG_DMEM_WIDTH - 1) or zero;
when BGT => v.branch := not (dat_a(CFG_DMEM_WIDTH - 1) or zero);
when BGE => v.branch := not dat_a(CFG_DMEM_WIDTH - 1);
when others => v.branch := '0';
end case;
end if;
 
-- Handle CMPU
IF ( exec_i.ctrl_ex.operation AND NOT (alu_src_a(CFG_DMEM_WIDTH - 1) XOR alu_src_b(CFG_DMEM_WIDTH - 1))) = '1' THEN
if ( exec_i.ctrl_ex.operation and not (alu_src_a(CFG_DMEM_WIDTH - 1) xor alu_src_b(CFG_DMEM_WIDTH - 1))) = '1' then
-- Set MSB
v.alu_result(CFG_DMEM_WIDTH - 1 DOWNTO 0) := (NOT result(CFG_DMEM_WIDTH - 1)) & result(CFG_DMEM_WIDTH - 2 DOWNTO 0);
ELSE
v.alu_result(CFG_DMEM_WIDTH - 1 downto 0) := (not result(CFG_DMEM_WIDTH - 1)) & result(CFG_DMEM_WIDTH - 2 downto 0);
else
-- Use ALU result
v.alu_result := result(CFG_DMEM_WIDTH - 1 DOWNTO 0);
END IF;
v.alu_result := result(CFG_DMEM_WIDTH - 1 downto 0);
end if;
 
v.program_counter := exec_i.program_counter;
 
-- Determine flush signals
v.flush_id := v.branch;
v_reg.flush_ex := v.branch AND NOT exec_i.ctrl_ex.delay;
v_reg.flush_ex := v.branch and not exec_i.ctrl_ex.delay;
 
rin <= v;
rin <= v;
regin <= v_reg;
 
END PROCESS;
end process;
 
execute_seq: PROCESS(clk_i)
PROCEDURE proc_execute_reset IS
BEGIN
r.alu_result <= (OTHERS => '0');
r.dat_d <= (OTHERS => '0');
execute_seq: process(clk_i)
procedure proc_execute_reset is
begin
r.alu_result <= (others => '0');
r.dat_d <= (others => '0');
r.branch <= '0';
r.program_counter <= (OTHERS => '0');
r.program_counter <= (others => '0');
r.flush_id <= '0';
r.ctrl_mem.mem_write <= '0';
r.ctrl_mem.mem_read <= '0';
r.ctrl_mem.transfer_size <= WORD;
r.ctrl_wb.reg_d <= (OTHERS => '0');
r.ctrl_wb.reg_write <= '0';
r.ctrl_wrb.reg_d <= (others => '0');
r.ctrl_wrb.reg_write <= '0';
reg.carry <= '0';
reg.flush_ex <= '0';
END PROCEDURE proc_execute_reset;
BEGIN
IF rising_edge(clk_i) THEN
IF rst_i = '1' THEN
end procedure proc_execute_reset;
begin
if rising_edge(clk_i) then
if rst_i = '1' then
proc_execute_reset;
ELSIF ena_i = '1' THEN
r <= rin;
elsif ena_i = '1' then
r <= rin;
reg <= regin;
END IF;
END IF;
END PROCESS;
END arch;
end if;
end if;
end process;
end arch;
/mblite/trunk/hw/core/decode.vhd
14,16 → 14,16
--
----------------------------------------------------------------------------------------------
 
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 decode IS GENERIC
entity decode is generic
(
G_INTERRUPT : boolean := CFG_INTERRUPT;
G_USE_HW_MUL : boolean := CFG_USE_HW_MUL;
30,41 → 30,41
G_USE_BARREL : boolean := CFG_USE_BARREL;
G_DEBUG : boolean := CFG_DEBUG
);
PORT
port
(
decode_o : OUT decode_out_type;
gprf_o : OUT gprf_out_type;
decode_i : IN decode_in_type;
ena_i : IN std_logic;
rst_i : IN std_logic;
clk_i : IN std_logic
decode_o : out decode_out_type;
gprf_o : out gprf_out_type;
decode_i : in decode_in_type;
ena_i : in std_logic;
rst_i : in std_logic;
clk_i : in std_logic
);
END decode;
end decode;
 
ARCHITECTURE arch OF decode IS
architecture arch of decode is
 
TYPE decode_reg_type IS RECORD
instruction : std_logic_vector(CFG_IMEM_WIDTH - 1 DOWNTO 0);
program_counter : std_logic_vector(CFG_IMEM_SIZE - 1 DOWNTO 0);
immediate : std_logic_vector(15 DOWNTO 0);
is_immediate : std_logic;
type decode_reg_type is record
instruction : std_logic_vector(CFG_IMEM_WIDTH - 1 downto 0);
program_counter : std_logic_vector(CFG_IMEM_SIZE - 1 downto 0);
immediate : std_logic_vector(15 downto 0);
is_immediate : std_logic;
msr_interrupt_enable : std_logic;
interrupt : std_logic;
delay_interrupt : std_logic;
END RECORD;
interrupt : std_logic;
delay_interrupt : std_logic;
end record;
 
SIGNAL r, rin : decode_out_type;
SIGNAL reg, regin : decode_reg_type;
signal r, rin : decode_out_type;
signal reg, regin : decode_reg_type;
 
SIGNAL wb_dat_d : std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0);
signal wb_dat_d : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
 
BEGIN
begin
 
decode_o.imm <= r.imm;
 
decode_o.ctrl_ex <= r.ctrl_ex;
decode_o.ctrl_mem <= r.ctrl_mem;
decode_o.ctrl_wb <= r.ctrl_wb;
decode_o.ctrl_wrb <= r.ctrl_wrb;
 
decode_o.reg_a <= r.reg_a;
decode_o.reg_b <= r.reg_b;
74,70 → 74,72
decode_o.fwd_dec_result <= r.fwd_dec_result;
decode_o.fwd_dec <= r.fwd_dec;
 
decode_comb: PROCESS(decode_i,decode_i.ctrl_wb,
decode_i.ctrl_mem_wb,
decode_i.ctrl_mem_wb.transfer_size,
decode_comb: process(decode_i,decode_i.ctrl_wrb,
decode_i.ctrl_mem_wrb,
decode_i.instruction,
decode_i.ctrl_mem_wrb.transfer_size,
r,r.ctrl_ex,r.ctrl_mem,
r.ctrl_mem.transfer_size,r.ctrl_wb,
r.ctrl_mem.transfer_size,r.ctrl_wrb,
r.ctrl_wrb.reg_d,
r.fwd_dec,reg)
 
VARIABLE v : decode_out_type;
VARIABLE v_reg : decode_reg_type;
VARIABLE opcode : std_logic_vector(5 DOWNTO 0);
VARIABLE instruction : std_logic_vector(CFG_IMEM_WIDTH - 1 DOWNTO 0);
VARIABLE program_counter : std_logic_vector(CFG_IMEM_SIZE - 1 DOWNTO 0);
VARIABLE mem_result : std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0);
variable v : decode_out_type;
variable v_reg : decode_reg_type;
variable opcode : std_logic_vector(5 downto 0);
variable instruction : std_logic_vector(CFG_IMEM_WIDTH - 1 downto 0);
variable program_counter : std_logic_vector(CFG_IMEM_SIZE - 1 downto 0);
variable mem_result : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
 
BEGIN
begin
v := r;
v_reg := reg;
 
-- Default register values (NOP)
v_reg.immediate := (OTHERS => '0');
v_reg.immediate := (others => '0');
v_reg.is_immediate := '0';
v_reg.program_counter := decode_i.program_counter;
v_reg.instruction := decode_i.instruction;
 
IF decode_i.ctrl_mem_wb.mem_read = '1' THEN
mem_result := align_mem_load(decode_i.mem_result, decode_i.ctrl_mem_wb.transfer_size, decode_i.alu_result(1 DOWNTO 0));
ELSE
if decode_i.ctrl_mem_wrb.mem_read = '1' then
mem_result := align_mem_load(decode_i.mem_result, decode_i.ctrl_mem_wrb.transfer_size, decode_i.alu_result(1 downto 0));
else
mem_result := decode_i.alu_result;
END IF;
end if;
 
wb_dat_d <= mem_result;
 
IF G_INTERRUPT = true THEN
if G_INTERRUPT = true then
v_reg.delay_interrupt := '0';
END IF;
end if;
 
IF CFG_REG_FWD_WB = true THEN
if CFG_REG_FWD_WRB = true then
v.fwd_dec_result := mem_result;
v.fwd_dec := decode_i.ctrl_wb;
ELSE
v.fwd_dec_result := (OTHERS => '0');
v.fwd_dec.reg_d := (OTHERS => '0');
v.fwd_dec := decode_i.ctrl_wrb;
else
v.fwd_dec_result := (others => '0');
v.fwd_dec.reg_d := (others => '0');
v.fwd_dec.reg_write := '0';
END IF;
end if;
 
IF (NOT decode_i.flush_id AND r.ctrl_mem.mem_read AND (compare(decode_i.instruction(20 DOWNTO 16), r.ctrl_wb.reg_d) OR compare(decode_i.instruction(15 DOWNTO 11), r.ctrl_wb.reg_d))) = '1' THEN
if (not decode_i.flush_id and r.ctrl_mem.mem_read and (compare(decode_i.instruction(20 downto 16), r.ctrl_wrb.reg_d) or compare(decode_i.instruction(15 downto 11), r.ctrl_wrb.reg_d))) = '1' then
-- A hazard occurred on register a or b
 
-- set current instruction and program counter to 0
instruction := (OTHERS => '0');
program_counter := (OTHERS => '0');
instruction := (others => '0');
program_counter := (others => '0');
 
v.hazard := '1';
 
ELSIF CFG_MEM_FWD_WB = false AND (NOT decode_i.flush_id AND r.ctrl_mem.mem_read AND compare(decode_i.instruction(25 DOWNTO 21), r.ctrl_wb.reg_d)) = '1' THEN
elsif CFG_MEM_FWD_WRB = false and (not decode_i.flush_id and r.ctrl_mem.mem_read and compare(decode_i.instruction(25 downto 21), r.ctrl_wrb.reg_d)) = '1' then
-- A hazard occurred on register d
 
-- set current instruction and program counter to 0
instruction := (OTHERS => '0');
program_counter := (OTHERS => '0');
instruction := (others => '0');
program_counter := (others => '0');
 
v.hazard := '1';
 
ELSIF r.hazard = '1' THEN
elsif r.hazard = '1' then
-- Recover from hazard. Insert latched instruction
 
instruction := reg.instruction;
144,34 → 146,34
program_counter := reg.program_counter;
v.hazard := '0';
 
ELSE
else
 
instruction := decode_i.instruction;
program_counter := decode_i.program_counter;
v.hazard := '0';
 
END IF;
end if;
 
v.program_counter := program_counter;
opcode := instruction(31 DOWNTO 26);
v.ctrl_wb.reg_d := instruction(25 DOWNTO 21);
v.reg_a := instruction(20 DOWNTO 16);
v.reg_b := instruction(15 DOWNTO 11);
opcode := instruction(31 downto 26);
v.ctrl_wrb.reg_d := instruction(25 downto 21);
v.reg_a := instruction(20 downto 16);
v.reg_b := instruction(15 downto 11);
 
-- SET IMM value
IF reg.is_immediate = '1' THEN
v.imm := reg.immediate & instruction(15 DOWNTO 0);
ELSE
v.imm := sign_extend(instruction(15 DOWNTO 0), instruction(15), 32);
END IF;
if reg.is_immediate = '1' then
v.imm := reg.immediate & instruction(15 downto 0);
else
v.imm := sign_extend(instruction(15 downto 0), instruction(15), 32);
end if;
 
-- Register if an interrupt occurs
IF G_INTERRUPT = true THEN
IF v_reg.msr_interrupt_enable = '1' AND decode_i.interrupt = '1' THEN
if G_INTERRUPT = true then
if v_reg.msr_interrupt_enable = '1' and decode_i.interrupt = '1' then
v_reg.interrupt := '1';
v_reg.msr_interrupt_enable := '0';
END IF;
END IF;
end if;
end if;
 
v.ctrl_ex.alu_op := ALU_ADD;
v.ctrl_ex.alu_src_a := ALU_SRC_REGA;
178,15 → 180,15
v.ctrl_ex.alu_src_b := ALU_SRC_REGB;
v.ctrl_ex.operation := '0';
v.ctrl_ex.carry := CARRY_ZERO;
v.ctrl_ex.carry_keep := CARRY_NOT_KEEP;
v.ctrl_ex.carry_keep := CARRY_KEEP;
v.ctrl_ex.delay := '0';
v.ctrl_ex.branch_cond := NOP;
v.ctrl_mem.mem_write := '0';
v.ctrl_mem.transfer_size := WORD;
v.ctrl_mem.mem_read := '0';
v.ctrl_wb.reg_write := '0';
v.ctrl_wrb.reg_write := '0';
 
IF G_INTERRUPT = true AND (v_reg.interrupt = '1' AND reg.delay_interrupt = '0' AND decode_i.flush_id = '0' AND v.hazard = '0' AND r.ctrl_ex.delay = '0' AND reg.is_immediate = '0') THEN
if G_INTERRUPT = true and (v_reg.interrupt = '1' and reg.delay_interrupt = '0' and decode_i.flush_id = '0' and v.hazard = '0' and r.ctrl_ex.delay = '0' and reg.is_immediate = '0') then
-- IF an interrupt occured
-- AND the current instruction is not a branch or return instruction,
-- AND the current instruction is not in a delay slot,
194,29 → 196,29
v_reg.msr_interrupt_enable := '0';
v_reg.interrupt := '0';
 
v.reg_a := (OTHERS => '0');
v.reg_b := (OTHERS => '0');
v.reg_a := (others => '0');
v.reg_b := (others => '0');
 
v.imm := X"00000010";
v.ctrl_wb.reg_d := "01110";
v.ctrl_wrb.reg_d := "01110";
 
v.ctrl_ex.branch_cond := BNC;
v.ctrl_ex.alu_src_a := ALU_SRC_ZERO;
v.ctrl_ex.alu_src_b := ALU_SRC_IMM;
v.ctrl_wb.reg_write := '1';
v.ctrl_wrb.reg_write := '1';
 
ELSIF (decode_i.flush_id OR v.hazard) = '1' THEN
elsif (decode_i.flush_id or v.hazard) = '1' then
-- clearing these registers is not necessary, but facilitates debugging.
-- On the other hand performance improves when disabled.
IF G_DEBUG = true THEN
v.program_counter := (OTHERS => '0');
v.ctrl_wb.reg_d := (OTHERS => '0');
v.reg_a := (OTHERS => '0');
v.reg_b := (OTHERS => '0');
v.imm := (OTHERS => '0');
END IF;
if G_DEBUG = true then
v.program_counter := (others => '0');
v.ctrl_wrb.reg_d := (others => '0');
v.reg_a := (others => '0');
v.reg_b := (others => '0');
v.imm := (others => '0');
end if;
 
ELSIF is_zero(opcode(5 DOWNTO 4)) = '1' THEN
elsif is_zero(opcode(5 downto 4)) = '1' then
-- ADD, SUBTRACT OR COMPARE
 
-- Alu operation
223,141 → 225,142
v.ctrl_ex.alu_op := ALU_ADD;
 
-- Source operand A
IF opcode(0) = '1' THEN
if opcode(0) = '1' then
v.ctrl_ex.alu_src_a := ALU_SRC_NOT_REGA;
ELSE
else
v.ctrl_ex.alu_src_a := ALU_SRC_REGA;
END IF;
end if;
 
-- Source operand B
IF opcode(3) = '1' THEN
if opcode(3) = '1' then
v.ctrl_ex.alu_src_b := ALU_SRC_IMM;
ELSE
else
v.ctrl_ex.alu_src_b := ALU_SRC_REGB;
END IF;
end if;
 
IF (compare(opcode, "000101") AND instruction(1)) = '1' THEN
if (compare(opcode, "000101") and instruction(1)) = '1' then
v.ctrl_ex.operation := '1';
END IF;
end if;
 
-- Carry
CASE opcode(1 DOWNTO 0) IS
WHEN "00" => v.ctrl_ex.carry := CARRY_ZERO;
WHEN "01" => v.ctrl_ex.carry := CARRY_ONE;
WHEN OTHERS => v.ctrl_ex.carry := CARRY_ALU;
END CASE;
case opcode(1 downto 0) is
when "00" => v.ctrl_ex.carry := CARRY_ZERO;
when "01" => v.ctrl_ex.carry := CARRY_ONE;
when others => v.ctrl_ex.carry := CARRY_ALU;
end case;
 
-- Carry keep
IF opcode(2) = '1' THEN
if opcode(2) = '1' then
v.ctrl_ex.carry_keep := CARRY_KEEP;
ELSE
else
v.ctrl_ex.carry_keep := CARRY_NOT_KEEP;
END IF;
end if;
 
-- Flag writeback if reg_d != 0
v.ctrl_wb.reg_write := is_not_zero(v.ctrl_wb.reg_d);
v.ctrl_wrb.reg_write := is_not_zero(v.ctrl_wrb.reg_d);
 
ELSIF (compare(opcode(5 DOWNTO 2), "1000") OR compare(opcode(5 DOWNTO 2), "1010")) = '1' THEN
elsif (compare(opcode(5 downto 2), "1000") or compare(opcode(5 downto 2), "1010")) = '1' then
-- OR, AND, XOR, ANDN
-- ORI, ANDI, XORI, ANDNI
CASE opcode(1 DOWNTO 0) IS
WHEN "00" => v.ctrl_ex.alu_op := ALU_OR;
WHEN "10" => v.ctrl_ex.alu_op := ALU_XOR;
WHEN OTHERS => v.ctrl_ex.alu_op := ALU_AND;
END CASE;
case opcode(1 downto 0) is
when "00" => v.ctrl_ex.alu_op := ALU_OR;
when "10" => v.ctrl_ex.alu_op := ALU_XOR;
when others => v.ctrl_ex.alu_op := ALU_AND;
end case;
 
IF opcode(3) = '1' AND compare(opcode(1 DOWNTO 0), "11") = '1' THEN
if opcode(3) = '1' and compare(opcode(1 downto 0), "11") = '1' then
v.ctrl_ex.alu_src_b := ALU_SRC_NOT_IMM;
ELSIF opcode(3) = '1' THEN
elsif opcode(3) = '1' then
v.ctrl_ex.alu_src_b := ALU_SRC_IMM;
ELSIF opcode(3) = '0' AND compare(opcode(1 DOWNTO 0), "11") = '1' THEN
elsif opcode(3) = '0' and compare(opcode(1 downto 0), "11") = '1' then
v.ctrl_ex.alu_src_b := ALU_SRC_NOT_REGB;
ELSE
else
v.ctrl_ex.alu_src_b := ALU_SRC_REGB;
END IF;
end if;
 
-- Flag writeback if reg_d != 0
v.ctrl_wb.reg_write := is_not_zero(v.ctrl_wb.reg_d);
v.ctrl_wrb.reg_write := is_not_zero(v.ctrl_wrb.reg_d);
 
ELSIF compare(opcode, "101100") = '1' THEN
elsif compare(opcode, "101100") = '1' then
-- IMM instruction
v_reg.immediate := instruction(15 DOWNTO 0);
v_reg.immediate := instruction(15 downto 0);
v_reg.is_immediate := '1';
 
ELSIF compare(opcode, "100100") = '1' THEN
elsif compare(opcode, "100100") = '1' then
-- SHIFT, SIGN EXTEND
IF compare(instruction(6 DOWNTO 5), "11") = '1' THEN
IF instruction(0) = '1' THEN
if compare(instruction(6 downto 5), "11") = '1' then
if instruction(0) = '1' then
v.ctrl_ex.alu_op:= ALU_SEXT16;
ELSE
else
v.ctrl_ex.alu_op:= ALU_SEXT8;
END IF;
ELSE
end if;
else
v.ctrl_ex.alu_op:= ALU_SHIFT;
CASE instruction(6 DOWNTO 5) IS
WHEN "10" => v.ctrl_ex.carry := CARRY_ZERO;
WHEN "01" => v.ctrl_ex.carry := CARRY_ALU;
WHEN OTHERS => v.ctrl_ex.carry := CARRY_ARITH;
END CASE;
END IF;
v.ctrl_ex.carry_keep := CARRY_NOT_KEEP;
case instruction(6 downto 5) is
when "10" => v.ctrl_ex.carry := CARRY_ZERO;
when "01" => v.ctrl_ex.carry := CARRY_ALU;
when others => v.ctrl_ex.carry := CARRY_ARITH;
end case;
end if;
 
-- Flag writeback if reg_d != 0
v.ctrl_wb.reg_write := is_not_zero(v.ctrl_wb.reg_d);
v.ctrl_wrb.reg_write := is_not_zero(v.ctrl_wrb.reg_d);
 
ELSIF (compare(opcode, "100110") OR compare(opcode, "101110")) = '1' THEN
elsif (compare(opcode, "100110") or compare(opcode, "101110")) = '1' then
-- BRANCH UNCONDITIONAL
 
v.ctrl_ex.branch_cond := BNC;
 
IF opcode(3) = '1' THEN
if opcode(3) = '1' then
v.ctrl_ex.alu_src_b := ALU_SRC_IMM;
ELSE
else
v.ctrl_ex.alu_src_b := ALU_SRC_REGB;
END IF;
end if;
 
-- WRITE THE RESULT ALSO TO REGISTER D
IF v.reg_a(2) = '1' THEN
if v.reg_a(2) = '1' then
-- Flag writeback if reg_d != 0
v.ctrl_wb.reg_write := is_not_zero(v.ctrl_wb.reg_d);
END IF;
v.ctrl_wrb.reg_write := is_not_zero(v.ctrl_wrb.reg_d);
end if;
 
IF v.reg_a(3) = '1' THEN
if v.reg_a(3) = '1' then
v.ctrl_ex.alu_src_a := ALU_SRC_ZERO;
ELSE
else
v.ctrl_ex.alu_src_a := ALU_SRC_PC;
END IF;
end if;
 
IF G_INTERRUPT = true THEN
if G_INTERRUPT = true then
v_reg.delay_interrupt := '1';
END IF;
end if;
v.ctrl_ex.delay := v.reg_a(4);
 
ELSIF (compare(opcode, "100111") OR compare(opcode, "101111")) = '1' THEN
elsif (compare(opcode, "100111") or compare(opcode, "101111")) = '1' then
-- BRANCH CONDITIONAL
v.ctrl_ex.alu_op := ALU_ADD;
v.ctrl_ex.alu_src_a := ALU_SRC_PC;
 
IF opcode(3) = '1' THEN
if opcode(3) = '1' then
v.ctrl_ex.alu_src_b := ALU_SRC_IMM;
ELSE
else
v.ctrl_ex.alu_src_b := ALU_SRC_REGB;
END IF;
end if;
 
CASE v.ctrl_wb.reg_d(2 DOWNTO 0) IS
WHEN "000" => v.ctrl_ex.branch_cond := BEQ;
WHEN "001" => v.ctrl_ex.branch_cond := BNE;
WHEN "010" => v.ctrl_ex.branch_cond := BLT;
WHEN "011" => v.ctrl_ex.branch_cond := BLE;
WHEN "100" => v.ctrl_ex.branch_cond := BGT;
WHEN OTHERS => v.ctrl_ex.branch_cond := BGE;
END CASE;
case v.ctrl_wrb.reg_d(2 downto 0) is
when "000" => v.ctrl_ex.branch_cond := BEQ;
when "001" => v.ctrl_ex.branch_cond := BNE;
when "010" => v.ctrl_ex.branch_cond := BLT;
when "011" => v.ctrl_ex.branch_cond := BLE;
when "100" => v.ctrl_ex.branch_cond := BGT;
when others => v.ctrl_ex.branch_cond := BGE;
end case;
 
IF G_INTERRUPT = true THEN
if G_INTERRUPT = true then
v_reg.delay_interrupt := '1';
END IF;
v.ctrl_ex.delay := v.ctrl_wb.reg_d(4);
end if;
v.ctrl_ex.delay := v.ctrl_wrb.reg_d(4);
 
ELSIF compare(opcode, "101101") = '1' THEN
elsif compare(opcode, "101101") = '1' then
-- RETURN
 
v.ctrl_ex.branch_cond := BNC;
364,133 → 367,133
v.ctrl_ex.alu_src_b := ALU_SRC_IMM;
v.ctrl_ex.delay := '1';
 
IF G_INTERRUPT = true THEN
IF v.ctrl_wb.reg_d(0) = '1' THEN
if G_INTERRUPT = true then
if v.ctrl_wrb.reg_d(0) = '1' then
v_reg.msr_interrupt_enable := '1';
END IF;
end if;
v_reg.delay_interrupt := '1';
END IF;
end if;
 
ELSIF compare(opcode(5 DOWNTO 4), "11") = '1' THEN
elsif compare(opcode(5 downto 4), "11") = '1' then
-- SW, LW
v.ctrl_ex.alu_op := ALU_ADD;
v.ctrl_ex.alu_src_a := ALU_SRC_REGA;
 
IF opcode(3) = '1' THEN
if opcode(3) = '1' then
v.ctrl_ex.alu_src_b := ALU_SRC_IMM;
ELSE
else
v.ctrl_ex.alu_src_b := ALU_SRC_REGB;
END IF;
end if;
 
v.ctrl_ex.carry := CARRY_ZERO;
 
IF opcode(2) = '1' THEN
if opcode(2) = '1' then
-- Store
v.ctrl_mem.mem_write := '1';
v.ctrl_mem.mem_read := '0';
v.ctrl_wb.reg_write := '0';
ELSE
v.ctrl_mem.mem_read := '0';
v.ctrl_wrb.reg_write := '0';
else
-- Load
v.ctrl_mem.mem_write := '0';
v.ctrl_mem.mem_read := '1';
v.ctrl_wb.reg_write := is_not_zero(v.ctrl_wb.reg_d);
END IF;
v.ctrl_mem.mem_read := '1';
v.ctrl_wrb.reg_write := is_not_zero(v.ctrl_wrb.reg_d);
end if;
 
CASE opcode(1 DOWNTO 0) IS
WHEN "00" => v.ctrl_mem.transfer_size := BYTE;
WHEN "01" => v.ctrl_mem.transfer_size := HALFWORD;
WHEN OTHERS => v.ctrl_mem.transfer_size := WORD;
END CASE;
case opcode(1 downto 0) is
when "00" => v.ctrl_mem.transfer_size := BYTE;
when "01" => v.ctrl_mem.transfer_size := HALFWORD;
when others => v.ctrl_mem.transfer_size := WORD;
end case;
 
v.ctrl_ex.delay := '0';
 
ELSIF G_USE_HW_MUL = true AND (compare(opcode, "010000") OR compare(opcode, "011000")) = '1' THEN
elsif G_USE_HW_MUL = true and (compare(opcode, "010000") or compare(opcode, "011000")) = '1' then
 
v.ctrl_ex.alu_op := ALU_MUL;
 
IF opcode(3) = '1' THEN
if opcode(3) = '1' then
v.ctrl_ex.alu_src_b := ALU_SRC_IMM;
ELSE
else
v.ctrl_ex.alu_src_b := ALU_SRC_REGB;
END IF;
end if;
 
v.ctrl_wb.reg_write := is_not_zero(v.ctrl_wb.reg_d);
v.ctrl_wrb.reg_write := is_not_zero(v.ctrl_wrb.reg_d);
 
ELSIF G_USE_BARREL = true AND (compare(opcode, "010001") OR compare(opcode, "011001")) = '1' THEN
elsif G_USE_BARREL = true and (compare(opcode, "010001") or compare(opcode, "011001")) = '1' then
 
v.ctrl_ex.alu_op := ALU_BS;
 
IF opcode(3) = '1' THEN
if opcode(3) = '1' then
v.ctrl_ex.alu_src_b := ALU_SRC_IMM;
ELSE
else
v.ctrl_ex.alu_src_b := ALU_SRC_REGB;
END IF;
end if;
 
v.ctrl_wb.reg_write := is_not_zero(v.ctrl_wb.reg_d);
v.ctrl_wrb.reg_write := is_not_zero(v.ctrl_wrb.reg_d);
 
ELSE
else
-- UNKNOWN OPCODE
NULL;
END IF;
null;
end if;
 
rin <= v;
regin <= v_reg;
 
END PROCESS;
end process;
 
decode_seq: PROCESS(clk_i)
PROCEDURE proc_reset_decode IS
BEGIN
r.reg_a <= (OTHERS => '0');
r.reg_b <= (OTHERS => '0');
r.imm <= (OTHERS => '0');
r.program_counter <= (OTHERS => '0');
r.hazard <= '0';
r.ctrl_ex.alu_op <= ALU_ADD;
r.ctrl_ex.alu_src_a <= ALU_SRC_REGA;
r.ctrl_ex.alu_src_b <= ALU_SRC_REGB;
r.ctrl_ex.operation <= '0';
r.ctrl_ex.carry <= CARRY_ZERO;
r.ctrl_ex.carry_keep <= CARRY_NOT_KEEP;
r.ctrl_ex.delay <= '0';
r.ctrl_ex.branch_cond <= NOP;
r.ctrl_mem.mem_write <= '0';
r.ctrl_mem.transfer_size <= WORD;
r.ctrl_mem.mem_read <= '0';
r.ctrl_wb.reg_d <= (OTHERS => '0');
r.ctrl_wb.reg_write <= '0';
r.fwd_dec_result <= (OTHERS => '0');
r.fwd_dec.reg_d <= (OTHERS => '0');
r.fwd_dec.reg_write <= '0';
reg.instruction <= (OTHERS => '0');
reg.program_counter <= (OTHERS => '0');
reg.immediate <= (OTHERS => '0');
reg.is_immediate <= '0';
reg.msr_interrupt_enable <= '1';
reg.interrupt <= '0';
reg.delay_interrupt <= '0';
END PROCEDURE proc_reset_decode;
BEGIN
IF rising_edge(clk_i) THEN
IF rst_i = '1' THEN
decode_seq: process(clk_i)
procedure proc_reset_decode is
begin
r.reg_a <= (others => '0');
r.reg_b <= (others => '0');
r.imm <= (others => '0');
r.program_counter <= (others => '0');
r.hazard <= '0';
r.ctrl_ex.alu_op <= ALU_ADD;
r.ctrl_ex.alu_src_a <= ALU_SRC_REGA;
r.ctrl_ex.alu_src_b <= ALU_SRC_REGB;
r.ctrl_ex.operation <= '0';
r.ctrl_ex.carry <= CARRY_ZERO;
r.ctrl_ex.carry_keep <= CARRY_NOT_KEEP;
r.ctrl_ex.delay <= '0';
r.ctrl_ex.branch_cond <= NOP;
r.ctrl_mem.mem_write <= '0';
r.ctrl_mem.transfer_size <= WORD;
r.ctrl_mem.mem_read <= '0';
r.ctrl_wrb.reg_d <= (others => '0');
r.ctrl_wrb.reg_write <= '0';
r.fwd_dec_result <= (others => '0');
r.fwd_dec.reg_d <= (others => '0');
r.fwd_dec.reg_write <= '0';
reg.instruction <= (others => '0');
reg.program_counter <= (others => '0');
reg.immediate <= (others => '0');
reg.is_immediate <= '0';
reg.msr_interrupt_enable <= '1';
reg.interrupt <= '0';
reg.delay_interrupt <= '0';
end procedure proc_reset_decode;
begin
if rising_edge(clk_i) then
if rst_i = '1' then
proc_reset_decode;
ELSIF ena_i = '1' THEN
elsif ena_i = '1' then
r <= rin;
reg <= regin;
END IF;
END IF;
END PROCESS;
end if;
end if;
end process;
 
gprf0 : gprf PORT MAP
gprf0 : gprf port map
(
gprf_o => gprf_o,
gprf_i.adr_a_i => rin.reg_a,
gprf_i.adr_b_i => rin.reg_b,
gprf_i.adr_d_i => rin.ctrl_wb.reg_d,
gprf_i.adr_d_i => rin.ctrl_wrb.reg_d,
gprf_i.dat_w_i => wb_dat_d,
gprf_i.adr_w_i => decode_i.ctrl_wb.reg_d,
gprf_i.wre_i => decode_i.ctrl_wb.reg_write,
gprf_i.adr_w_i => decode_i.ctrl_wrb.reg_d,
gprf_i.wre_i => decode_i.ctrl_wrb.reg_write,
ena_i => ena_i,
clk_i => clk_i
);
END arch;
end arch;
/mblite/trunk/hw/core/core.vhd
12,15 → 12,15
--
----------------------------------------------------------------------------------------------
 
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;
library mblite;
use mblite.config_Pkg.all;
use mblite.core_Pkg.all;
 
ENTITY core IS GENERIC
entity core is generic
(
G_INTERRUPT : boolean := CFG_INTERRUPT;
G_USE_HW_MUL : boolean := CFG_USE_HW_MUL;
27,45 → 27,45
G_USE_BARREL : boolean := CFG_USE_BARREL;
G_DEBUG : boolean := CFG_DEBUG
);
PORT
port
(
imem_o : OUT imem_out_type;
dmem_o : OUT dmem_out_type;
imem_i : IN imem_in_type;
dmem_i : IN dmem_in_type;
int_i : IN std_logic;
rst_i : IN std_logic;
clk_i : IN std_logic
imem_o : out imem_out_type;
dmem_o : out dmem_out_type;
imem_i : in imem_in_type;
dmem_i : in dmem_in_type;
int_i : in std_logic;
rst_i : in std_logic;
clk_i : in std_logic
);
END core;
end core;
 
ARCHITECTURE arch OF core IS
architecture arch of core is
 
SIGNAL fetch_i : fetch_in_type;
SIGNAL fetch_o : fetch_out_type;
signal fetch_i : fetch_in_type;
signal fetch_o : fetch_out_type;
 
SIGNAL decode_i : decode_in_type;
SIGNAL decode_o : decode_out_type;
signal decode_i : decode_in_type;
signal decode_o : decode_out_type;
 
SIGNAL gprf_o : gprf_out_type;
signal gprf_o : gprf_out_type;
 
SIGNAL exec_i : execute_in_type;
SIGNAL exec_o : execute_out_type;
signal exec_i : execute_in_type;
signal exec_o : execute_out_type;
 
SIGNAL mem_i : mem_in_type;
SIGNAL mem_o : mem_out_type;
signal mem_i : mem_in_type;
signal mem_o : mem_out_type;
 
SIGNAL ena_i : std_logic;
signal ena_i : std_logic;
 
BEGIN
begin
 
ena_i <= dmem_i.ena_i;
 
fetch_i.hazard <= decode_o.hazard;
fetch_i.branch <= exec_o.branch;
fetch_i.branch_target <= exec_o.alu_result(CFG_IMEM_SIZE - 1 DOWNTO 0);
fetch_i.branch_target <= exec_o.alu_result(CFG_IMEM_SIZE - 1 downto 0);
 
fetch0 : fetch PORT MAP
fetch0 : fetch port map
(
fetch_o => fetch_o,
imem_o => imem_o,
77,14 → 77,14
 
decode_i.program_counter <= fetch_o.program_counter;
decode_i.instruction <= imem_i.dat_i;
decode_i.ctrl_wb <= mem_o.ctrl_wb;
decode_i.ctrl_mem_wb <= mem_o.ctrl_mem_wb;
decode_i.ctrl_wrb <= mem_o.ctrl_wrb;
decode_i.ctrl_mem_wrb <= mem_o.ctrl_mem_wrb;
decode_i.mem_result <= dmem_i.dat_i;
decode_i.alu_result <= mem_o.alu_result;
decode_i.interrupt <= int_i;
decode_i.flush_id <= exec_o.flush_id;
 
decode0: decode GENERIC MAP
decode0: decode generic map
(
G_INTERRUPT => G_INTERRUPT,
G_USE_HW_MUL => G_USE_HW_MUL,
91,7 → 91,7
G_USE_BARREL => G_USE_BARREL,
G_DEBUG => G_DEBUG
)
PORT MAP
port map
(
decode_o => decode_o,
decode_i => decode_i,
112,21 → 112,21
 
exec_i.imm <= decode_o.imm;
exec_i.program_counter <= decode_o.program_counter;
exec_i.ctrl_wb <= decode_o.ctrl_wb;
exec_i.ctrl_wrb <= decode_o.ctrl_wrb;
exec_i.ctrl_mem <= decode_o.ctrl_mem;
exec_i.ctrl_ex <= decode_o.ctrl_ex;
 
exec_i.fwd_mem <= mem_o.ctrl_wb;
exec_i.fwd_mem <= mem_o.ctrl_wrb;
exec_i.mem_result <= dmem_i.dat_i;
exec_i.alu_result <= mem_o.alu_result;
exec_i.ctrl_mem_wb <= mem_o.ctrl_mem_wb;
exec_i.ctrl_mem_wrb <= mem_o.ctrl_mem_wrb;
 
execute0 : execute GENERIC MAP
execute0 : execute generic map
(
G_USE_HW_MUL => G_USE_HW_MUL,
G_USE_BARREL => G_USE_BARREL
)
PORT MAP
port map
(
exec_o => exec_o,
exec_i => exec_i,
139,11 → 139,11
mem_i.program_counter <= exec_o.program_counter;
mem_i.branch <= exec_o.branch;
mem_i.dat_d <= exec_o.dat_d;
mem_i.ctrl_wb <= exec_o.ctrl_wb;
mem_i.ctrl_wrb <= exec_o.ctrl_wrb;
mem_i.ctrl_mem <= exec_o.ctrl_mem;
mem_i.mem_result <= dmem_i.dat_i;
 
mem0 : mem PORT MAP
mem0 : mem port map
(
mem_o => mem_o,
dmem_o => dmem_o,
153,4 → 153,4
clk_i => clk_i
);
 
END arch;
end arch;
/mblite/trunk/hw/core/core_Pkg.vhd
13,29 → 13,33
--
----------------------------------------------------------------------------------------------
 
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.std_Pkg.ALL;
library mblite;
use mblite.config_Pkg.all;
use mblite.std_Pkg.all;
 
PACKAGE core_Pkg IS
package core_Pkg is
 
constant C_8_ZEROS : std_logic_vector ( 7 downto 0) := (others => '0');
constant C_16_ZEROS : std_logic_vector (15 downto 0) := (others => '0');
constant C_24_ZEROS : std_logic_vector (23 downto 0) := (others => '0');
constant C_32_ZEROS : std_logic_vector (31 downto 0) := (others => '0');
----------------------------------------------------------------------------------------------
-- TYPES USED IN MB-LITE
----------------------------------------------------------------------------------------------
 
TYPE alu_operation IS (ALU_ADD, ALU_OR, ALU_AND, ALU_XOR, ALU_SHIFT, ALU_SEXT8, ALU_SEXT16, ALU_MUL, ALU_BS);
TYPE src_type_a IS (ALU_SRC_REGA, ALU_SRC_NOT_REGA, ALU_SRC_PC, ALU_SRC_ZERO);
TYPE src_type_b IS (ALU_SRC_REGB, ALU_SRC_NOT_REGB, ALU_SRC_IMM, ALU_SRC_NOT_IMM);
TYPE carry_type IS (CARRY_ZERO, CARRY_ONE, CARRY_ALU, CARRY_ARITH);
TYPE carry_keep_type IS (CARRY_NOT_KEEP, CARRY_KEEP);
TYPE branch_condition IS (NOP, BNC, BEQ, BNE, BLT, BLE, BGT, BGE);
TYPE transfer_size IS (WORD, HALFWORD, BYTE);
type alu_operation is (ALU_ADD, ALU_OR, ALU_AND, ALU_XOR, ALU_SHIFT, ALU_SEXT8, ALU_SEXT16, ALU_MUL, ALU_BS);
type src_type_a is (ALU_SRC_REGA, ALU_SRC_NOT_REGA, ALU_SRC_PC, ALU_SRC_ZERO);
type src_type_b is (ALU_SRC_REGB, ALU_SRC_NOT_REGB, ALU_SRC_IMM, ALU_SRC_NOT_IMM);
type carry_type is (CARRY_ZERO, CARRY_ONE, CARRY_ALU, CARRY_ARITH);
type carry_keep_type is (CARRY_NOT_KEEP, CARRY_KEEP);
type branch_condition is (NOP, BNC, BEQ, BNE, BLT, BLE, BGT, BGE);
type transfer_size is (WORD, HALFWORD, BYTE);
 
TYPE ctrl_execution IS RECORD
type ctrl_execution is record
alu_op : alu_operation;
alu_src_a : src_type_a;
alu_src_b : src_type_b;
44,455 → 48,404
carry_keep : carry_keep_type;
branch_cond : branch_condition;
delay : std_logic;
END RECORD;
end record;
 
TYPE ctrl_memory IS RECORD
type ctrl_memory is record
mem_write : std_logic;
mem_read : std_logic;
transfer_size : transfer_size;
END RECORD;
end record;
 
TYPE ctrl_memory_writeback_type IS RECORD
type ctrl_memory_writeback_type is record
mem_read : std_logic;
transfer_size : transfer_size;
END RECORD;
end record;
 
TYPE forward_type IS RECORD
reg_d : std_logic_vector(CFG_GPRF_SIZE - 1 DOWNTO 0);
type forward_type is record
reg_d : std_logic_vector(CFG_GPRF_SIZE - 1 downto 0);
reg_write : std_logic;
END RECORD;
end record;
 
TYPE imem_in_type IS RECORD
dat_i : std_logic_vector(CFG_IMEM_WIDTH - 1 DOWNTO 0);
END RECORD;
type imem_in_type is record
dat_i : std_logic_vector(CFG_IMEM_WIDTH - 1 downto 0);
end record;
 
TYPE imem_out_type IS RECORD
adr_o : std_logic_vector(CFG_IMEM_SIZE - 1 DOWNTO 0);
type imem_out_type is record
adr_o : std_logic_vector(CFG_IMEM_SIZE - 1 downto 0);
ena_o : std_logic;
END RECORD;
end record;
 
TYPE fetch_in_type IS RECORD
hazard : std_logic;
branch : std_logic;
branch_target : std_logic_vector(CFG_IMEM_SIZE - 1 DOWNTO 0);
END RECORD;
type fetch_in_type is record
hazard : std_logic;
branch : std_logic;
branch_target : std_logic_vector(CFG_IMEM_SIZE - 1 downto 0);
end record;
 
TYPE fetch_out_type IS RECORD
program_counter : std_logic_vector(CFG_IMEM_SIZE - 1 DOWNTO 0);
END RECORD;
type fetch_out_type is record
program_counter : std_logic_vector(CFG_IMEM_SIZE - 1 downto 0);
end record;
 
TYPE gprf_out_type IS RECORD
dat_a_o : std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0);
dat_b_o : std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0);
dat_d_o : std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0);
END RECORD;
type gprf_out_type is record
dat_a_o : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
dat_b_o : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
dat_d_o : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
end record;
 
TYPE decode_in_type IS RECORD
program_counter : std_logic_vector(CFG_IMEM_SIZE - 1 DOWNTO 0);
instruction : std_logic_vector(CFG_IMEM_WIDTH - 1 DOWNTO 0);
ctrl_wb : forward_type;
ctrl_mem_wb : ctrl_memory_writeback_type;
mem_result : std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0);
alu_result : std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0);
type decode_in_type is record
program_counter : std_logic_vector(CFG_IMEM_SIZE - 1 downto 0);
instruction : std_logic_vector(CFG_IMEM_WIDTH - 1 downto 0);
ctrl_wrb : forward_type;
ctrl_mem_wrb : ctrl_memory_writeback_type;
mem_result : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
alu_result : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
interrupt : std_logic;
flush_id : std_logic;
END RECORD;
end record;
 
TYPE decode_out_type IS RECORD
reg_a : std_logic_vector(CFG_GPRF_SIZE - 1 DOWNTO 0);
reg_b : std_logic_vector(CFG_GPRF_SIZE - 1 DOWNTO 0);
imm : std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0);
program_counter : std_logic_vector(CFG_IMEM_SIZE - 1 DOWNTO 0);
type decode_out_type is record
reg_a : std_logic_vector(CFG_GPRF_SIZE - 1 downto 0);
reg_b : std_logic_vector(CFG_GPRF_SIZE - 1 downto 0);
imm : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
program_counter : std_logic_vector(CFG_IMEM_SIZE - 1 downto 0);
hazard : std_logic;
ctrl_ex : ctrl_execution;
ctrl_mem : ctrl_memory;
ctrl_wb : forward_type;
fwd_dec_result : std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0);
ctrl_wrb : forward_type;
fwd_dec_result : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
fwd_dec : forward_type;
END RECORD;
end record;
 
TYPE gprf_in_type IS RECORD
adr_a_i : std_logic_vector(CFG_GPRF_SIZE - 1 DOWNTO 0);
adr_b_i : std_logic_vector(CFG_GPRF_SIZE - 1 DOWNTO 0);
adr_d_i : std_logic_vector(CFG_GPRF_SIZE - 1 DOWNTO 0);
dat_w_i : std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0);
adr_w_i : std_logic_vector(CFG_GPRF_SIZE - 1 DOWNTO 0);
type gprf_in_type is record
adr_a_i : std_logic_vector(CFG_GPRF_SIZE - 1 downto 0);
adr_b_i : std_logic_vector(CFG_GPRF_SIZE - 1 downto 0);
adr_d_i : std_logic_vector(CFG_GPRF_SIZE - 1 downto 0);
dat_w_i : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
adr_w_i : std_logic_vector(CFG_GPRF_SIZE - 1 downto 0);
wre_i : std_logic;
END RECORD;
end record;
 
TYPE execute_out_type IS RECORD
alu_result : std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0);
dat_d : std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0);
type execute_out_type is record
alu_result : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
dat_d : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
branch : std_logic;
program_counter : std_logic_vector(CFG_IMEM_SIZE - 1 DOWNTO 0);
program_counter : std_logic_vector(CFG_IMEM_SIZE - 1 downto 0);
flush_id : std_logic;
ctrl_mem : ctrl_memory;
ctrl_wb : forward_type;
END RECORD;
ctrl_wrb : forward_type;
end record;
 
TYPE execute_in_type IS RECORD
reg_a : std_logic_vector(CFG_GPRF_SIZE - 1 DOWNTO 0);
dat_a : std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0);
reg_b : std_logic_vector(CFG_GPRF_SIZE - 1 DOWNTO 0);
dat_b : std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0);
dat_d : std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0);
imm : std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0);
program_counter : std_logic_vector(CFG_IMEM_SIZE - 1 DOWNTO 0);
type execute_in_type is record
reg_a : std_logic_vector(CFG_GPRF_SIZE - 1 downto 0);
dat_a : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
reg_b : std_logic_vector(CFG_GPRF_SIZE - 1 downto 0);
dat_b : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
dat_d : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
imm : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
program_counter : std_logic_vector(CFG_IMEM_SIZE - 1 downto 0);
fwd_dec : forward_type;
fwd_dec_result : std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0);
fwd_dec_result : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
fwd_mem : forward_type;
ctrl_ex : ctrl_execution;
ctrl_mem : ctrl_memory;
ctrl_wb : forward_type;
ctrl_mem_wb : ctrl_memory_writeback_type;
mem_result : std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0);
alu_result : std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0);
ctrl_wrb : forward_type;
ctrl_mem_wrb : ctrl_memory_writeback_type;
mem_result : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
alu_result : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
 
END RECORD;
end record;
 
TYPE mem_in_type IS RECORD
dat_d : std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0);
alu_result : std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0);
mem_result : std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0);
program_counter : std_logic_vector(CFG_IMEM_SIZE - 1 DOWNTO 0);
type mem_in_type is record
dat_d : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
alu_result : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
mem_result : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
program_counter : std_logic_vector(CFG_IMEM_SIZE - 1 downto 0);
branch : std_logic;
ctrl_mem : ctrl_memory;
ctrl_wb : forward_type;
END RECORD;
ctrl_wrb : forward_type;
end record;
 
TYPE mem_out_type IS RECORD
alu_result : std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0);
ctrl_wb : forward_type;
ctrl_mem_wb : ctrl_memory_writeback_type;
END RECORD;
type mem_out_type is record
alu_result : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
ctrl_wrb : forward_type;
ctrl_mem_wrb : ctrl_memory_writeback_type;
end record;
 
TYPE dmem_in_type IS RECORD
dat_i : std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0);
type dmem_in_type is record
dat_i : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
ena_i : std_logic;
END RECORD;
end record;
 
TYPE dmem_out_type IS RECORD
dat_o : std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0);
adr_o : std_logic_vector(CFG_DMEM_SIZE - 1 DOWNTO 0);
sel_o : std_logic_vector(3 DOWNTO 0);
type dmem_out_type is record
dat_o : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
adr_o : std_logic_vector(CFG_DMEM_SIZE - 1 downto 0);
sel_o : std_logic_vector(3 downto 0);
we_o : std_logic;
ena_o : std_logic;
END RECORD;
end record;
 
TYPE dmem_in_array_type IS ARRAY(NATURAL RANGE <>) OF dmem_in_type;
TYPE dmem_out_array_type IS ARRAY(NATURAL RANGE <>) OF dmem_out_type;
type dmem_in_array_type is array(natural range <>) of dmem_in_type;
type dmem_out_array_type is array(natural range <>) of dmem_out_type;
 
-- WB-master inputs from the wb-slaves
TYPE wb_mst_in_type IS RECORD
clk_i : std_logic; -- master clock input
rst_i : std_logic; -- synchronous active high reset
dat_i : std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0); -- databus input
ack_i : std_logic; -- buscycle acknowledge input
int_i : std_logic; -- interrupt request input
END RECORD;
type wb_mst_in_type is record
clk_i : std_logic; -- master clock input
rst_i : std_logic; -- synchronous active high reset
dat_i : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0); -- databus input
ack_i : std_logic; -- buscycle acknowledge input
int_i : std_logic; -- interrupt request input
end record;
 
-- WB-master outputs to the wb-slaves
TYPE wb_mst_out_type IS RECORD
adr_o : std_logic_vector(CFG_DMEM_SIZE - 1 DOWNTO 0); -- address bits
dat_o : std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0); -- databus output
we_o : std_logic; -- write enable output
stb_o : std_logic; -- strobe signals
sel_o : std_logic_vector(3 DOWNTO 0); -- select output array
cyc_o : std_logic; -- valid BUS cycle output
END RECORD;
type wb_mst_out_type is record
adr_o : std_logic_vector(CFG_DMEM_SIZE - 1 downto 0); -- address bits
dat_o : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0); -- databus output
we_o : std_logic; -- write enable output
stb_o : std_logic; -- strobe signals
sel_o : std_logic_vector(3 downto 0); -- select output array
cyc_o : std_logic; -- valid BUS cycle output
end record;
 
-- WB-slave inputs, from the WB-master
TYPE wb_slv_in_type IS RECORD
clk_i : std_logic; -- master clock input
rst_i : std_logic; -- synchronous active high reset
adr_i : std_logic_vector(CFG_DMEM_SIZE - 1 DOWNTO 0); -- address bits
dat_i : std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0); -- Databus input
we_i : std_logic; -- Write enable input
stb_i : std_logic; -- strobe signals / core select signal
sel_i : std_logic_vector(3 DOWNTO 0); -- select output array
cyc_i : std_logic; -- valid BUS cycle input
END RECORD;
type wb_slv_in_type is record
clk_i : std_logic; -- master clock input
rst_i : std_logic; -- synchronous active high reset
adr_i : std_logic_vector(CFG_DMEM_SIZE - 1 downto 0); -- address bits
dat_i : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0); -- Databus input
we_i : std_logic; -- Write enable input
stb_i : std_logic; -- strobe signals / core select signal
sel_i : std_logic_vector(3 downto 0); -- select output array
cyc_i : std_logic; -- valid BUS cycle input
end record;
 
-- WB-slave outputs to the WB-master
TYPE wb_slv_out_type IS RECORD
dat_o : std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0); -- Databus output
ack_o : std_logic; -- Bus cycle acknowledge output
int_o : std_logic; -- interrupt request output
END RECORD;
type wb_slv_out_type is record
dat_o : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0); -- Databus output
ack_o : std_logic; -- Bus cycle acknowledge output
int_o : std_logic; -- interrupt request output
end record;
 
----------------------------------------------------------------------------------------------
-- COMPONENTS USED IN MB-LITE
----------------------------------------------------------------------------------------------
 
COMPONENT core GENERIC
(
G_INTERRUPT : boolean := CFG_INTERRUPT;
G_USE_HW_MUL : boolean := CFG_USE_HW_MUL;
G_USE_BARREL : boolean := CFG_USE_BARREL;
G_DEBUG : boolean := CFG_DEBUG
);
PORT
(
imem_o : OUT imem_out_type;
dmem_o : OUT dmem_out_type;
imem_i : IN imem_in_type;
dmem_i : IN dmem_in_type;
int_i : IN std_logic;
rst_i : IN std_logic;
clk_i : IN std_logic
);
END COMPONENT;
component core
generic (
G_INTERRUPT : boolean := CFG_INTERRUPT;
G_USE_HW_MUL : boolean := CFG_USE_HW_MUL;
G_USE_BARREL : boolean := CFG_USE_BARREL;
G_DEBUG : boolean := CFG_DEBUG
);
port (
imem_o : out imem_out_type;
dmem_o : out dmem_out_type;
imem_i : in imem_in_type;
dmem_i : in dmem_in_type;
int_i : in std_logic;
rst_i : in std_logic;
clk_i : in std_logic
);
end component;
 
COMPONENT core_wb GENERIC
(
G_INTERRUPT : boolean := CFG_INTERRUPT;
G_USE_HW_MUL : boolean := CFG_USE_HW_MUL;
G_USE_BARREL : boolean := CFG_USE_BARREL;
G_DEBUG : boolean := CFG_DEBUG
);
PORT
(
imem_o : OUT imem_out_type;
wb_o : OUT wb_mst_out_type;
imem_i : IN imem_in_type;
wb_i : IN wb_mst_in_type
);
END COMPONENT;
component core_wb
generic (
G_INTERRUPT : boolean := CFG_INTERRUPT;
G_USE_HW_MUL : boolean := CFG_USE_HW_MUL;
G_USE_BARREL : boolean := CFG_USE_BARREL;
G_DEBUG : boolean := CFG_DEBUG
);
port (
imem_o : out imem_out_type;
wb_o : out wb_mst_out_type;
imem_i : in imem_in_type;
wb_i : in wb_mst_in_type
);
end component;
 
COMPONENT core_wb_adapter PORT
(
dmem_i : OUT dmem_in_type;
wb_o : OUT wb_mst_out_type;
dmem_o : IN dmem_out_type;
wb_i : IN wb_mst_in_type
);
END COMPONENT;
component core_wb_adapter
port (
dmem_i : out dmem_in_type;
wb_o : out wb_mst_out_type;
dmem_o : in dmem_out_type;
wb_i : in wb_mst_in_type
);
end component;
 
COMPONENT core_wb_async_adapter PORT
(
dmem_i : OUT dmem_in_type;
wb_o : OUT wb_mst_out_type;
dmem_o : IN dmem_out_type;
wb_i : IN wb_mst_in_type
);
END COMPONENT;
component core_wb_async_adapter
port (
dmem_i : out dmem_in_type;
wb_o : out wb_mst_out_type;
dmem_o : in dmem_out_type;
wb_i : in wb_mst_in_type
);
end component;
 
COMPONENT fetch PORT
(
fetch_o : OUT fetch_out_type;
imem_o : OUT imem_out_type;
fetch_i : IN fetch_in_type;
rst_i : IN std_logic;
ena_i : IN std_logic;
clk_i : IN std_logic
);
END COMPONENT;
component fetch
port (
fetch_o : out fetch_out_type;
imem_o : out imem_out_type;
fetch_i : in fetch_in_type;
rst_i : in std_logic;
ena_i : in std_logic;
clk_i : in std_logic
);
end component;
 
COMPONENT decode GENERIC
(
G_INTERRUPT : boolean := CFG_INTERRUPT;
G_USE_HW_MUL : boolean := CFG_USE_HW_MUL;
G_USE_BARREL : boolean := CFG_USE_BARREL;
G_DEBUG : boolean := CFG_DEBUG
);
PORT
(
decode_o : OUT decode_out_type;
gprf_o : OUT gprf_out_type;
decode_i : IN decode_in_type;
ena_i : IN std_logic;
rst_i : IN std_logic;
clk_i : IN std_logic
);
END COMPONENT;
component decode
generic (
G_INTERRUPT : boolean := CFG_INTERRUPT;
G_USE_HW_MUL : boolean := CFG_USE_HW_MUL;
G_USE_BARREL : boolean := CFG_USE_BARREL;
G_DEBUG : boolean := CFG_DEBUG
);
port (
decode_o : out decode_out_type;
gprf_o : out gprf_out_type;
decode_i : in decode_in_type;
ena_i : in std_logic;
rst_i : in std_logic;
clk_i : in std_logic
);
end component;
 
COMPONENT gprf PORT
(
gprf_o : OUT gprf_out_type;
gprf_i : IN gprf_in_type;
ena_i : IN std_logic;
clk_i : IN std_logic
);
END COMPONENT;
component gprf
port (
gprf_o : out gprf_out_type;
gprf_i : in gprf_in_type;
ena_i : in std_logic;
clk_i : in std_logic
);
end component;
 
COMPONENT execute GENERIC
(
G_USE_HW_MUL : boolean := CFG_USE_HW_MUL;
G_USE_BARREL : boolean := CFG_USE_BARREL
);
PORT
(
exec_o : OUT execute_out_type;
exec_i : IN execute_in_type;
ena_i : IN std_logic;
rst_i : IN std_logic;
clk_i : IN std_logic
);
END COMPONENT;
component execute
generic (
G_USE_HW_MUL : boolean := CFG_USE_HW_MUL;
G_USE_BARREL : boolean := CFG_USE_BARREL
);
port (
exec_o : out execute_out_type;
exec_i : in execute_in_type;
ena_i : in std_logic;
rst_i : in std_logic;
clk_i : in std_logic
);
end component;
 
COMPONENT mem PORT
(
mem_o : OUT mem_out_type;
dmem_o : OUT dmem_out_type;
mem_i : IN mem_in_type;
ena_i : IN std_logic;
rst_i : IN std_logic;
clk_i : IN std_logic
);
END COMPONENT;
component mem
port (
mem_o : out mem_out_type;
dmem_o : out dmem_out_type;
mem_i : in mem_in_type;
ena_i : in std_logic;
rst_i : in std_logic;
clk_i : in std_logic
);
end component;
 
COMPONENT core_address_decoder GENERIC
(
G_NUM_SLAVES : positive := CFG_NUM_SLAVES
);
PORT
(
m_dmem_i : OUT dmem_in_type;
s_dmem_o : OUT dmem_out_array_type;
m_dmem_o : IN dmem_out_type;
s_dmem_i : IN dmem_in_array_type;
clk_i : IN std_logic
);
END COMPONENT;
component core_address_decoder
generic (
G_NUM_SLAVES : positive := CFG_NUM_SLAVES
);
port (
m_dmem_i : out dmem_in_type;
s_dmem_o : out dmem_out_array_type;
m_dmem_o : in dmem_out_type;
s_dmem_i : in dmem_in_array_type;
clk_i : in std_logic
);
end component;
----------------------------------------------------------------------------------------------
-- FUNCTIONS USED IN MB-LITE
----------------------------------------------------------------------------------------------
 
FUNCTION select_register_data(reg_dat, reg, wb_dat : std_logic_vector; write : std_logic) RETURN std_logic_vector;
FUNCTION forward_condition(reg_write : std_logic; reg_a, reg_d : std_logic_vector) RETURN std_logic;
FUNCTION align_mem_load(data : std_logic_vector; size : transfer_size; address : std_logic_vector) RETURN std_logic_vector;
FUNCTION align_mem_store(data : std_logic_vector; size : transfer_size) RETURN std_logic_vector;
FUNCTION decode_mem_store(address : std_logic_vector(1 DOWNTO 0); size : transfer_size) RETURN std_logic_vector;
function select_register_data (reg_dat, reg, wb_dat : std_logic_vector; write : std_logic) return std_logic_vector;
function forward_condition (reg_write : std_logic; reg_a, reg_d : std_logic_vector) return std_logic;
function align_mem_load (data : std_logic_vector; size : transfer_size; address : std_logic_vector) return std_logic_vector;
function align_mem_store (data : std_logic_vector; size : transfer_size) return std_logic_vector;
function decode_mem_store (address : std_logic_vector(1 downto 0); size : transfer_size) return std_logic_vector;
 
END core_Pkg;
end core_Pkg;
 
PACKAGE BODY core_Pkg IS
package body core_Pkg is
 
-- This function select the register value:
-- A) zero
-- B) bypass value read from register file
-- C) value from register file
FUNCTION select_register_data(reg_dat, reg, wb_dat : std_logic_vector; write : std_logic) RETURN std_logic_vector IS
VARIABLE tmp : std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0);
BEGIN
IF CFG_REG_FORCE_ZERO = true AND is_zero(reg) = '1' THEN
tmp := (OTHERS => '0');
ELSIF CFG_REG_FWD_WB = true AND write = '1' THEN
function select_register_data (reg_dat, reg, wb_dat : std_logic_vector; write : std_logic) return std_logic_vector is
variable tmp : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
begin
if CFG_REG_FORCE_ZERO = true and is_zero(reg) = '1' then
tmp := (others => '0');
elsif CFG_REG_FWD_WRB = true and write = '1' then
tmp := wb_dat;
ELSE
else
tmp := reg_dat;
END IF;
RETURN tmp;
END select_register_data;
end if;
return tmp;
end select_register_data;
 
-- This function checks if a forwarding condition is met. The condition is met of register A and D match
-- and the signal needs to be written back to the register file.
FUNCTION forward_condition(reg_write : std_logic; reg_a, reg_d : std_logic_vector ) RETURN std_logic IS
BEGIN
RETURN reg_write AND compare(reg_a, reg_d);
END forward_condition;
function forward_condition (reg_write : std_logic; reg_a, reg_d : std_logic_vector ) return std_logic is
begin
return reg_write and compare(reg_a, reg_d);
end forward_condition;
 
-- This function aligns the memory load operation. The load byte-order is defined here.
FUNCTION align_mem_load(data : std_logic_vector; size : transfer_size; address : std_logic_vector ) RETURN std_logic_vector IS
BEGIN
IF CFG_BYTE_ORDER = false THEN
-- Little endian decoding
CASE size IS
WHEN byte =>
CASE address(1 DOWNTO 0) IS
WHEN "00" => RETURN "000000000000000000000000" & data(CFG_DMEM_WIDTH/4 - 1 DOWNTO 0);
WHEN "01" => RETURN "000000000000000000000000" & data(CFG_DMEM_WIDTH/2 - 1 DOWNTO CFG_DMEM_WIDTH/4);
WHEN "10" => RETURN "000000000000000000000000" & data(3*CFG_DMEM_WIDTH/4 - 1 DOWNTO CFG_DMEM_WIDTH/2);
WHEN "11" => RETURN "000000000000000000000000" & data(CFG_DMEM_WIDTH - 1 DOWNTO 3*CFG_DMEM_WIDTH/4);
WHEN OTHERS => RETURN "00000000000000000000000000000000";
END CASE;
WHEN halfword =>
CASE address(1 DOWNTO 0) IS
WHEN "00" => RETURN "0000000000000000" & data(CFG_DMEM_WIDTH/2 - 1 DOWNTO 0);
WHEN "10" => RETURN "0000000000000000" & data(CFG_DMEM_WIDTH - 1 DOWNTO CFG_DMEM_WIDTH/2);
WHEN OTHERS => RETURN "00000000000000000000000000000000";
END CASE;
WHEN OTHERS =>
RETURN data;
END CASE;
ELSE
-- Big endian decoding
CASE size IS
WHEN byte =>
CASE address(1 DOWNTO 0) IS
WHEN "00" => RETURN "000000000000000000000000" & data(CFG_DMEM_WIDTH - 1 DOWNTO 3*CFG_DMEM_WIDTH/4);
WHEN "01" => RETURN "000000000000000000000000" & data(3*CFG_DMEM_WIDTH/4 - 1 DOWNTO CFG_DMEM_WIDTH/2);
WHEN "10" => RETURN "000000000000000000000000" & data(CFG_DMEM_WIDTH/2 - 1 DOWNTO CFG_DMEM_WIDTH/4);
WHEN "11" => RETURN "000000000000000000000000" & data(CFG_DMEM_WIDTH/4 - 1 DOWNTO 0);
WHEN OTHERS => RETURN "00000000000000000000000000000000";
END CASE;
WHEN halfword =>
CASE address(1 DOWNTO 0) IS
WHEN "00" => RETURN "0000000000000000" & data(CFG_DMEM_WIDTH - 1 DOWNTO CFG_DMEM_WIDTH/2);
WHEN "10" => RETURN "0000000000000000" & data(CFG_DMEM_WIDTH/2 - 1 DOWNTO 0);
WHEN OTHERS => RETURN "00000000000000000000000000000000";
END CASE;
WHEN OTHERS =>
RETURN data;
END CASE;
END IF;
END align_mem_load;
-- This function aligns the memory load operation (Big endian decoding).
function align_mem_load (data : std_logic_vector; size : transfer_size; address : std_logic_vector ) return std_logic_vector is
begin
case size is
when byte =>
case address(1 downto 0) is
when "00" => return C_24_ZEROS & data(31 downto 24);
when "01" => return C_24_ZEROS & data(23 downto 16);
when "10" => return C_24_ZEROS & data(15 downto 8);
when "11" => return C_24_ZEROS & data( 7 downto 0);
when others => return C_32_ZEROS;
end case;
when halfword =>
case address(1 downto 0) is
when "00" => return C_16_ZEROS & data(31 downto 16);
when "10" => return C_16_ZEROS & data(15 downto 0);
when others => return C_32_ZEROS;
end case;
when others =>
return data;
end case;
end align_mem_load;
 
-- This function repeats the operand to all positions memory store operation.
FUNCTION align_mem_store(data : std_logic_vector; size : transfer_size) RETURN std_logic_vector IS
BEGIN
CASE size IS
WHEN byte => RETURN data( 7 DOWNTO 0) & data( 7 DOWNTO 0) & data(7 DOWNTO 0) & data(7 DOWNTO 0);
WHEN halfword => RETURN data(15 DOWNTO 0) & data(15 DOWNTO 0);
WHEN OTHERS => RETURN data;
END CASE;
END align_mem_store;
-- This function repeats the operand to all positions in a memory store operation.
function align_mem_store (data : std_logic_vector; size : transfer_size) return std_logic_vector is
begin
case size is
when byte => return data( 7 downto 0) & data( 7 downto 0) & data(7 downto 0) & data(7 downto 0);
when halfword => return data(15 downto 0) & data(15 downto 0);
when others => return data;
end case;
end align_mem_store;
 
-- This function selects the correct bytes for memory writes. The store byte-order (MSB / LSB) can be defined here.
FUNCTION decode_mem_store(address : std_logic_vector(1 DOWNTO 0); size : transfer_size) RETURN std_logic_vector IS
BEGIN
IF CFG_BYTE_ORDER = false THEN
-- Little endian encoding
CASE size IS
WHEN BYTE =>
CASE address IS
WHEN "00" => RETURN "0001";
WHEN "01" => RETURN "0010";
WHEN "10" => RETURN "0100";
WHEN "11" => RETURN "1000";
WHEN OTHERS => RETURN "0000";
END CASE;
WHEN HALFWORD =>
CASE address IS
WHEN "00" => RETURN "0011";
WHEN "10" => RETURN "1100";
WHEN OTHERS => RETURN "0000";
END CASE;
WHEN OTHERS =>
RETURN "1111";
END CASE;
ELSE
-- Big endian encoding
CASE size IS
WHEN BYTE =>
CASE address IS
WHEN "00" => RETURN "1000";
WHEN "01" => RETURN "0100";
WHEN "10" => RETURN "0010";
WHEN "11" => RETURN "0001";
WHEN OTHERS => RETURN "0000";
END CASE;
WHEN HALFWORD =>
CASE address IS
-- Big endian encoding
WHEN "10" => RETURN "0011";
WHEN "00" => RETURN "1100";
WHEN OTHERS => RETURN "0000";
END CASE;
WHEN OTHERS =>
RETURN "1111";
END CASE;
END IF;
END decode_mem_store;
-- This function selects the correct bytes for memory writes (Big endian encoding).
function decode_mem_store (address : std_logic_vector(1 downto 0); size : transfer_size) return std_logic_vector is
begin
case size is
when BYTE =>
case address is
when "00" => return "1000";
when "01" => return "0100";
when "10" => return "0010";
when "11" => return "0001";
when others => return "0000";
end case;
when HALFWORD =>
case address is
-- Big endian encoding
when "10" => return "0011";
when "00" => return "1100";
when others => return "0000";
end case;
when others =>
return "1111";
end case;
end decode_mem_store;
 
END core_Pkg;
end core_Pkg;
/mblite/trunk/hw/core/fetch.vhd
14,57 → 14,57
--
----------------------------------------------------------------------------------------------
 
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 fetch IS PORT
entity fetch is port
(
fetch_o : OUT fetch_out_type;
imem_o : OUT imem_out_type;
fetch_i : IN fetch_in_type;
rst_i : IN std_logic;
ena_i : IN std_logic;
clk_i : IN std_logic
fetch_o : out fetch_out_type;
imem_o : out imem_out_type;
fetch_i : in fetch_in_type;
rst_i : in std_logic;
ena_i : in std_logic;
clk_i : in std_logic
);
END fetch;
end fetch;
 
ARCHITECTURE arch OF fetch IS
SIGNAL r, rin : fetch_out_type;
BEGIN
architecture arch of fetch is
signal r, rin : fetch_out_type;
begin
 
fetch_o.program_counter <= r.program_counter;
imem_o.adr_o <= rin.program_counter;
imem_o.ena_o <= ena_i;
 
fetch_comb: PROCESS(fetch_i, r, rst_i)
VARIABLE v : fetch_out_type;
BEGIN
fetch_comb: process(fetch_i, r, rst_i)
variable v : fetch_out_type;
begin
v := r;
IF fetch_i.hazard = '1' THEN
if fetch_i.hazard = '1' then
v.program_counter := r.program_counter;
ELSIF fetch_i.branch = '1' THEN
elsif fetch_i.branch = '1' then
v.program_counter := fetch_i.branch_target;
ELSE
v.program_counter := increment(r.program_counter(CFG_IMEM_SIZE - 1 DOWNTO 2)) & "00";
END IF;
else
v.program_counter := increment(r.program_counter(CFG_IMEM_SIZE - 1 downto 2)) & "00";
end if;
rin <= v;
END PROCESS;
end process;
 
fetch_seq: PROCESS(clk_i)
BEGIN
IF rising_edge(clk_i) THEN
IF rst_i = '1' THEN
r.program_counter <= (OTHERS => '0');
ELSIF ena_i = '1' THEN
fetch_seq: process(clk_i)
begin
if rising_edge(clk_i) then
if rst_i = '1' then
r.program_counter <= (others => '0');
elsif ena_i = '1' then
r <= rin;
END IF;
END IF;
END PROCESS;
end if;
end if;
end process;
 
END arch;
end arch;
/mblite/trunk/hw/core/gprf.vhd
13,36 → 13,36
--
----------------------------------------------------------------------------------------------
 
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 gprf IS PORT
entity gprf is port
(
gprf_o : OUT gprf_out_type;
gprf_i : IN gprf_in_type;
ena_i : IN std_logic;
clk_i : IN std_logic
gprf_o : out gprf_out_type;
gprf_i : in gprf_in_type;
ena_i : in std_logic;
clk_i : in std_logic
);
END gprf;
end gprf;
 
-- This architecture is the default implementation. It
-- consists of three dual port memories. Other
-- architectures can be added while configurations can
-- control the implemented architecture.
ARCHITECTURE arch OF gprf IS
BEGIN
a : dsram GENERIC MAP
architecture arch of gprf is
begin
a : dsram generic map
(
WIDTH => CFG_DMEM_WIDTH,
SIZE => CFG_GPRF_SIZE
WIDTH => CFG_DMEM_WIDTH,
SIZE => CFG_GPRF_SIZE
)
PORT MAP
port map
(
dat_o => gprf_o.dat_a_o,
adr_i => gprf_i.adr_a_i,
53,12 → 53,12
clk_i => clk_i
);
 
b : dsram GENERIC MAP
b : dsram generic map
(
WIDTH => CFG_DMEM_WIDTH,
SIZE => CFG_GPRF_SIZE
WIDTH => CFG_DMEM_WIDTH,
SIZE => CFG_GPRF_SIZE
)
PORT MAP
port map
(
dat_o => gprf_o.dat_b_o,
adr_i => gprf_i.adr_b_i,
69,12 → 69,12
clk_i => clk_i
);
 
d : dsram GENERIC MAP
d : dsram generic map
(
WIDTH => CFG_DMEM_WIDTH,
SIZE => CFG_GPRF_SIZE
WIDTH => CFG_DMEM_WIDTH,
SIZE => CFG_GPRF_SIZE
)
PORT MAP
port map
(
dat_o => gprf_o.dat_d_o,
adr_i => gprf_i.adr_d_i,
84,4 → 84,4
wre_i => gprf_i.wre_i,
clk_i => clk_i
);
END arch;
end arch;
/mblite/trunk/hw/core/mem.vhd
20,88 → 20,88
--
----------------------------------------------------------------------------------------------
 
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 mem IS PORT
entity mem is port
(
mem_o : OUT mem_out_type;
dmem_o : OUT dmem_out_type;
mem_i : IN mem_in_type;
ena_i : IN std_logic;
rst_i : IN std_logic;
clk_i : IN std_logic
mem_o : out mem_out_type;
dmem_o : out dmem_out_type;
mem_i : in mem_in_type;
ena_i : in std_logic;
rst_i : in std_logic;
clk_i : in std_logic
);
END mem;
end mem;
 
ARCHITECTURE arch OF mem IS
SIGNAL r, rin : mem_out_type;
SIGNAL mem_result : std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0);
BEGIN
architecture arch of mem is
signal r, rin : mem_out_type;
signal mem_result : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
begin
-- connect pipline signals
mem_o.ctrl_wb <= r.ctrl_wb;
mem_o.ctrl_mem_wb <= r.ctrl_mem_wb;
mem_o.ctrl_wrb <= r.ctrl_wrb;
mem_o.ctrl_mem_wrb <= r.ctrl_mem_wrb;
mem_o.alu_result <= r.alu_result;
 
-- connect memory interface signals
dmem_o.dat_o <= mem_result;
dmem_o.sel_o <= decode_mem_store(mem_i.alu_result(1 DOWNTO 0), mem_i.ctrl_mem.transfer_size);
dmem_o.sel_o <= decode_mem_store(mem_i.alu_result(1 downto 0), mem_i.ctrl_mem.transfer_size);
dmem_o.we_o <= mem_i.ctrl_mem.mem_write;
dmem_o.adr_o <= mem_i.alu_result(CFG_DMEM_SIZE - 1 DOWNTO 0);
dmem_o.ena_o <= mem_i.ctrl_mem.mem_read OR mem_i.ctrl_mem.mem_write;
dmem_o.adr_o <= mem_i.alu_result(CFG_DMEM_SIZE - 1 downto 0);
dmem_o.ena_o <= mem_i.ctrl_mem.mem_read or mem_i.ctrl_mem.mem_write;
 
mem_comb: PROCESS(mem_i, mem_i.ctrl_wb, mem_i.ctrl_mem, r, r.ctrl_wb, r.ctrl_mem_wb)
VARIABLE v : mem_out_type;
VARIABLE intermediate : std_logic_vector(CFG_DMEM_WIDTH - 1 DOWNTO 0);
BEGIN
mem_comb: process(mem_i, mem_i.ctrl_wrb, mem_i.ctrl_mem, r, r.ctrl_wrb, r.ctrl_mem_wrb)
variable v : mem_out_type;
variable intermediate : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
begin
 
v := r;
v.ctrl_wb := mem_i.ctrl_wb;
v.ctrl_wrb := mem_i.ctrl_wrb;
 
IF mem_i.branch = '1' THEN
if mem_i.branch = '1' then
-- set alu result for branch and load instructions
v.alu_result := sign_extend(mem_i.program_counter, '0', 32);
ELSE
else
v.alu_result := mem_i.alu_result;
END IF;
end if;
 
-- Forward memory result
IF CFG_MEM_FWD_WB = true AND ( r.ctrl_mem_wb.mem_read AND compare(mem_i.ctrl_wb.reg_d, r.ctrl_wb.reg_d)) = '1' THEN
intermediate := align_mem_load(mem_i.mem_result, r.ctrl_mem_wb.transfer_size, r.alu_result(1 DOWNTO 0));
if CFG_MEM_FWD_WRB = true and ( r.ctrl_mem_wrb.mem_read and compare(mem_i.ctrl_wrb.reg_d, r.ctrl_wrb.reg_d)) = '1' then
intermediate := align_mem_load(mem_i.mem_result, r.ctrl_mem_wrb.transfer_size, r.alu_result(1 downto 0));
mem_result <= align_mem_store(intermediate, mem_i.ctrl_mem.transfer_size);
ELSE
else
mem_result <= mem_i.dat_d;
END IF;
end if;
 
v.ctrl_mem_wb.mem_read := mem_i.ctrl_mem.mem_read;
v.ctrl_mem_wb.transfer_size := mem_i.ctrl_mem.transfer_size;
v.ctrl_mem_wrb.mem_read := mem_i.ctrl_mem.mem_read;
v.ctrl_mem_wrb.transfer_size := mem_i.ctrl_mem.transfer_size;
 
rin <= v;
 
END PROCESS;
end process;
 
mem_seq: PROCESS(clk_i)
PROCEDURE proc_mem_reset IS
BEGIN
r.alu_result <= (OTHERS => '0');
r.ctrl_wb.reg_d <= (OTHERS => '0');
r.ctrl_wb.reg_write <= '0';
r.ctrl_mem_wb.mem_read <= '0';
r.ctrl_mem_wb.transfer_size <= WORD;
END PROCEDURE proc_mem_reset;
BEGIN
IF rising_edge(clk_i) THEN
IF rst_i = '1' THEN
mem_seq: process(clk_i)
procedure proc_mem_reset is
begin
r.alu_result <= (others => '0');
r.ctrl_wrb.reg_d <= (others => '0');
r.ctrl_wrb.reg_write <= '0';
r.ctrl_mem_wrb.mem_read <= '0';
r.ctrl_mem_wrb.transfer_size <= WORD;
end procedure proc_mem_reset;
begin
if rising_edge(clk_i) then
if rst_i = '1' then
proc_mem_reset;
ELSIF ena_i = '1' THEN
elsif ena_i = '1' then
r <= rin;
END IF;
END IF;
END PROCESS;
END arch;
end if;
end if;
end process;
end arch;
/mblite/trunk/hw/std/sram.vhd
11,43 → 11,42
--
----------------------------------------------------------------------------------------------
 
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 IS GENERIC
entity sram is generic
(
WIDTH : positive := 32;
SIZE : positive := 16
);
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;
end sram;
 
ARCHITECTURE arch OF sram IS
TYPE ram_type IS array(2 ** SIZE - 1 DOWNTO 0) OF std_logic_vector(WIDTH - 1 DOWNTO 0);
SIGNAL ram : ram_type;
BEGIN
PROCESS(clk_i)
BEGIN
IF rising_edge(clk_i) THEN
IF ena_i = '1' THEN
IF wre_i = '1' THEN
architecture arch of sram is
type ram_type is array(2 ** SIZE - 1 downto 0) of std_logic_vector(WIDTH - 1 downto 0);
signal ram : ram_type;
begin
process(clk_i)
begin
if rising_edge(clk_i) then
if 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;
/mblite/trunk/hw/std/dsram.vhd
13,43 → 13,43
--
----------------------------------------------------------------------------------------------
 
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 dsram IS GENERIC
entity dsram is generic
(
WIDTH : positive := 32;
SIZE : positive := 8
);
PORT
port
(
dat_o : OUT std_logic_vector(WIDTH - 1 DOWNTO 0);
adr_i : IN std_logic_vector(SIZE - 1 DOWNTO 0);
ena_i : IN std_logic;
dat_w_i : IN std_logic_vector(WIDTH - 1 DOWNTO 0);
adr_w_i : IN std_logic_vector(SIZE - 1 DOWNTO 0);
wre_i : IN std_logic;
clk_i : IN std_logic
dat_o : out std_logic_vector(WIDTH - 1 downto 0);
adr_i : in std_logic_vector(SIZE - 1 downto 0);
ena_i : in std_logic;
dat_w_i : in std_logic_vector(WIDTH - 1 downto 0);
adr_w_i : in std_logic_vector(SIZE - 1 downto 0);
wre_i : in std_logic;
clk_i : in std_logic
);
END dsram;
end dsram;
 
ARCHITECTURE arch OF dsram IS
TYPE ram_type IS array(2 ** SIZE - 1 DOWNTO 0) OF std_logic_vector(WIDTH - 1 DOWNTO 0);
SIGNAL ram : ram_type;
BEGIN
PROCESS(clk_i)
BEGIN
IF rising_edge(clk_i) THEN
IF ena_i = '1' THEN
IF wre_i = '1' THEN
architecture arch of dsram is
type ram_type is array(2 ** SIZE - 1 downto 0) of std_logic_vector(WIDTH - 1 downto 0);
signal ram : ram_type;
begin
process(clk_i)
begin
if rising_edge(clk_i) then
if ena_i = '1' then
if wre_i = '1' then
ram(my_conv_integer(adr_w_i)) <= dat_w_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;
/mblite/trunk/hw/std/sram_4en.vhd
14,80 → 14,80
--
----------------------------------------------------------------------------------------------
 
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 IS GENERIC
entity sram_4en is generic
(
WIDTH : positive := 32;
SIZE : positive := 16
);
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(WIDTH/8 - 1 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(WIDTH/8 - 1 downto 0);
ena_i : in std_logic;
clk_i : in std_logic
);
END sram_4en;
end sram_4en;
 
-- Although this memory is very easy to use in conjunction with Modelsims mem load, it is not
-- supported by many devices (although it comes straight from the library. Many devices give
-- cryptic synthesization errors on this implementation, so it is not the default.
ARCHITECTURE arch2 OF sram_4en IS
architecture arch2 of sram_4en is
 
TYPE ram_type IS array(2 ** SIZE - 1 DOWNTO 0) OF std_logic_vector(WIDTH - 1 DOWNTO 0);
TYPE sel_type IS array(WIDTH/8 - 1 DOWNTO 0) OF std_logic_vector(7 DOWNTO 0);
type ram_type is array(2 ** SIZE - 1 downto 0) of std_logic_vector(WIDTH - 1 downto 0);
type sel_type is array(WIDTH/8 - 1 downto 0) of std_logic_vector(7 downto 0);
 
SIGNAL ram: ram_type;
SIGNAL di: sel_type;
BEGIN
PROCESS(wre_i, dat_i, adr_i)
BEGIN
FOR i IN 0 TO WIDTH/8 - 1 LOOP
IF wre_i(i) = '1' THEN
di(i) <= dat_i((i+1)*8 - 1 DOWNTO i*8);
ELSE
di(i) <= ram(my_conv_integer(adr_i))((i+1)*8 - 1 DOWNTO i*8);
END IF;
END LOOP;
END PROCESS;
signal ram: ram_type;
signal di: sel_type;
begin
process(wre_i, dat_i, adr_i)
begin
for i in 0 to WIDTH/8 - 1 loop
if wre_i(i) = '1' then
di(i) <= dat_i((i+1)*8 - 1 downto i*8);
else
di(i) <= ram(my_conv_integer(adr_i))((i+1)*8 - 1 downto i*8);
end if;
end loop;
end process;
 
PROCESS(clk_i)
BEGIN
IF rising_edge(clk_i) THEN
IF ena_i = '1' THEN
process(clk_i)
begin
if rising_edge(clk_i) then
if ena_i = '1' then
ram(my_conv_integer(adr_i)) <= di(3) & di(2) & di(1) & di(0);
dat_o <= di(3) & di(2) & di(1) & di(0);
END IF;
END IF;
END PROCESS;
END arch2;
end if;
end if;
end process;
end arch2;
 
-- Less convenient but very general memory block with four separate write
-- enable signals. (4x8 bit)
ARCHITECTURE arch OF sram_4en IS
BEGIN
mem: FOR i IN 0 TO WIDTH/8 - 1 GENERATE
mem : sram GENERIC MAP
architecture arch of sram_4en is
begin
mem: for i in 0 to WIDTH/8 - 1 generate
mem : sram generic map
(
WIDTH => 8,
SIZE => SIZE
)
PORT MAP
port map
(
dat_o => dat_o((i+1)*8 - 1 DOWNTO i*8),
dat_i => dat_i((i+1)*8 - 1 DOWNTO i*8),
dat_o => dat_o((i+1)*8 - 1 downto i*8),
dat_i => dat_i((i+1)*8 - 1 downto i*8),
adr_i => adr_i,
wre_i => wre_i(i),
ena_i => ena_i,
clk_i => clk_i
);
END GENERATE;
END arch;
end generate;
end arch;
/mblite/trunk/hw/std/std_Pkg.vhd
11,9 → 11,9
--
----------------------------------------------------------------------------------------------
 
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
PACKAGE std_Pkg IS
 
21,147 → 21,145
-- STANDARD COMPONENTS IN STD_PKG
----------------------------------------------------------------------------------------------
 
COMPONENT sram GENERIC
component sram generic
(
WIDTH : positive;
SIZE : positive
);
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 GENERIC
component sram_4en generic
(
WIDTH : positive;
SIZE : positive
);
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;
 
COMPONENT dsram GENERIC
component dsram generic
(
WIDTH : positive;
SIZE : positive
);
PORT
port
(
dat_o : OUT std_logic_vector(WIDTH - 1 DOWNTO 0);
adr_i : IN std_logic_vector(SIZE - 1 DOWNTO 0);
ena_i : IN std_logic;
dat_w_i : IN std_logic_vector(WIDTH - 1 DOWNTO 0);
adr_w_i : IN std_logic_vector(SIZE - 1 DOWNTO 0);
wre_i : IN std_logic;
clk_i : IN std_logic
dat_o : out std_logic_vector(WIDTH - 1 downto 0);
adr_i : in std_logic_vector(SIZE - 1 downto 0);
ena_i : in std_logic;
dat_w_i : in std_logic_vector(WIDTH - 1 downto 0);
adr_w_i : in std_logic_vector(SIZE - 1 downto 0);
wre_i : in std_logic;
clk_i : in std_logic
);
END COMPONENT;
end component;
 
----------------------------------------------------------------------------------------------
-- FUNCTIONS IN STD_PKG
----------------------------------------------------------------------------------------------
 
FUNCTION v_or(d : std_logic_vector) RETURN std_logic;
FUNCTION is_zero(d : std_logic_vector) RETURN std_logic;
FUNCTION is_not_zero(d : std_logic_vector) RETURN std_logic;
FUNCTION my_conv_integer(a: std_logic_vector) RETURN integer;
FUNCTION notx(d : std_logic_vector) RETURN boolean;
FUNCTION compare(a, b : std_logic_vector) RETURN std_logic;
FUNCTION multiply(a, b : std_logic_vector) RETURN std_logic_vector;
FUNCTION sign_extend(value: std_logic_vector; fill: std_logic; size: positive) RETURN std_logic_vector;
FUNCTION add(a, b : std_logic_vector; ci: std_logic) RETURN std_logic_vector;
FUNCTION increment(a : std_logic_vector) RETURN std_logic_vector;
FUNCTION shift(value : std_logic_vector(31 DOWNTO 0); shamt: std_logic_vector(4 DOWNTO 0); s: std_logic; t: std_logic) RETURN std_logic_vector;
FUNCTION shift_left(value : std_logic_vector(31 DOWNTO 0); shamt : std_logic_vector(4 DOWNTO 0)) RETURN std_logic_vector;
FUNCTION shift_right(value : std_logic_vector(31 DOWNTO 0); shamt : std_logic_vector(4 DOWNTO 0); padding: std_logic) RETURN std_logic_vector;
function v_or(d : std_logic_vector) return std_logic;
function is_zero(d : std_logic_vector) return std_logic;
function is_not_zero(d : std_logic_vector) return std_logic;
function my_conv_integer(a: std_logic_vector) return integer;
function notx(d : std_logic_vector) return boolean;
function compare(a, b : std_logic_vector) return std_logic;
function multiply(a, b : std_logic_vector) return std_logic_vector;
function sign_extend(value: std_logic_vector; fill: std_logic; size: positive) return std_logic_vector;
function add(a, b : std_logic_vector; ci: std_logic) return std_logic_vector;
function increment(a : std_logic_vector) return std_logic_vector;
function shift(value : std_logic_vector(31 downto 0); shamt: std_logic_vector(4 downto 0); s: std_logic; t: std_logic) return std_logic_vector;
function shift_left(value : std_logic_vector(31 downto 0); shamt : std_logic_vector(4 downto 0)) return std_logic_vector;
function shift_right(value : std_logic_vector(31 downto 0); shamt : std_logic_vector(4 downto 0); padding: std_logic) return std_logic_vector;
 
END std_Pkg;
end std_Pkg;
 
PACKAGE BODY std_Pkg IS
 
-- Unary OR reduction
FUNCTION v_or(d : std_logic_vector) RETURN std_logic IS
VARIABLE z : std_logic;
BEGIN
function v_or(d : std_logic_vector) return std_logic is
variable z : std_logic;
begin
z := '0';
IF notx (d) THEN
FOR i IN d'range LOOP
z := z OR d(i);
END LOOP;
END IF;
RETURN z;
END;
if notx (d) then
for i in d'range loop
z := z or d(i);
end loop;
end if;
return z;
end;
 
-- Check for ones in the vector
FUNCTION is_not_zero(d : std_logic_vector) RETURN std_logic IS
VARIABLE z : std_logic_vector(d'range);
BEGIN
z := (OTHERS => '0');
IF notx(d) THEN
function is_not_zero(d : std_logic_vector) return std_logic is
variable z : std_logic_vector(d'range);
begin
z := (others => '0');
if notx(d) then
 
IF d = z THEN
RETURN '0';
ELSE
RETURN '1';
END IF;
if d = z then
return '0';
else
return '1';
end if;
 
ELSE
RETURN '0';
END IF;
END;
else
return '0';
end if;
end;
 
-- Check for ones in the vector
FUNCTION is_zero(d : std_logic_vector) RETURN std_logic IS
BEGIN
RETURN NOT is_not_zero(d);
END;
function is_zero(d : std_logic_vector) return std_logic is
begin
return not is_not_zero(d);
end;
 
-- rewrite conv_integer to avoid modelsim warnings
FUNCTION my_conv_integer(a : std_logic_vector) RETURN integer IS
VARIABLE res : integer RANGE 0 TO 2**a'length-1;
BEGIN
function my_conv_integer(a : std_logic_vector) return integer is
variable res : integer range 0 to 2**a'length-1;
begin
res := 0;
IF (notx(a)) THEN
if (notx(a)) then
res := to_integer(unsigned(a));
END IF;
RETURN res;
END;
end if;
return res;
end;
 
FUNCTION compare(a, b : std_logic_vector) RETURN std_logic IS
VARIABLE z : std_logic;
BEGIN
function compare(a, b : std_logic_vector) return std_logic is
variable z : std_logic;
begin
if notx(a & b) and a = b then
return '1';
else
return '0';
end if;
end;
 
IF notx(a & b) AND a = b THEN
RETURN '1';
ELSE
RETURN '0';
END IF;
 
END;
 
-- Unary NOT X test
FUNCTION notx(d : std_logic_vector) RETURN boolean IS
VARIABLE res : boolean;
BEGIN
function notx(d : std_logic_vector) return boolean is
variable res : boolean;
begin
res := true;
-- pragma translate_off
res := NOT is_x(d);
res := not is_x(d);
-- pragma translate_on
RETURN (res);
END;
return (res);
end;
 
-- -- 32 bit shifter
-- -- SYNOPSIS:
171,98 → 169,94
-- -- t 0 / 1: shift logical / arithmetic
-- -- PSEUDOCODE (from microblaze reference guide)
-- -- if S = 1 then
-- -- (rD) ← (rA) << (rB)[27:31]
-- -- (rD) = (rA) << (rB)[27:31]
-- -- else
-- -- if T = 1 then
-- -- if ((rB)[27:31]) ≠ 0 then
-- -- (rD)[0:(rB)[27:31]-1] ← (rA)[0]
-- -- (rD)[(rB)[27:31]:31] ← (rA) >> (rB)[27:31]
-- -- if ((rB)[27:31]) != 0 then
-- -- (rD)[0:(rB)[27:31]-1] = (rA)[0]
-- -- (rD)[(rB)[27:31]:31] = (rA) >> (rB)[27:31]
-- -- else
-- -- (rD) ← (rA)
-- -- (rD) = (rA)
-- -- else
-- -- (rD) ← (rA) >> (rB)[27:31]
-- -- (rD) = (rA) >> (rB)[27:31]
 
FUNCTION shift(value: std_logic_vector(31 DOWNTO 0); shamt: std_logic_vector(4 DOWNTO 0); s: std_logic; t: std_logic) RETURN std_logic_vector IS
BEGIN
IF s = '1' THEN
function shift(value: std_logic_vector(31 downto 0); shamt: std_logic_vector(4 downto 0); s: std_logic; t: std_logic) return std_logic_vector is
begin
if s = '1' then
-- left arithmetic or logical shift
RETURN shift_left(value, shamt);
ELSE
IF t = '1' THEN
return shift_left(value, shamt);
else
if t = '1' then
-- right arithmetic shift
RETURN shift_right(value, shamt, value(31));
ELSE
return shift_right(value, shamt, value(31));
else
-- right logical shift
RETURN shift_right(value, shamt, '0');
END IF;
END IF;
END;
return shift_right(value, shamt, '0');
end if;
end if;
end;
 
FUNCTION shift_left(value: std_logic_vector(31 DOWNTO 0); shamt: std_logic_vector(4 DOWNTO 0)) RETURN std_logic_vector IS
VARIABLE result: std_logic_vector(31 DOWNTO 0);
VARIABLE paddings: std_logic_vector(15 DOWNTO 0);
BEGIN
 
paddings := (OTHERS => '0');
function shift_left(value: std_logic_vector(31 downto 0); shamt: std_logic_vector(4 downto 0)) return std_logic_vector is
variable result: std_logic_vector(31 downto 0);
variable paddings: std_logic_vector(15 downto 0);
begin
paddings := (others => '0');
result := value;
IF (shamt(4) = '1') THEN result := result(15 DOWNTO 0) & paddings(15 DOWNTO 0); END IF;
IF (shamt(3) = '1') THEN result := result(23 DOWNTO 0) & paddings( 7 DOWNTO 0); END IF;
IF (shamt(2) = '1') THEN result := result(27 DOWNTO 0) & paddings( 3 DOWNTO 0); END IF;
IF (shamt(1) = '1') THEN result := result(29 DOWNTO 0) & paddings( 1 DOWNTO 0); END IF;
IF (shamt(0) = '1') THEN result := result(30 DOWNTO 0) & paddings( 0 ); END IF;
RETURN result;
if (shamt(4) = '1') then result := result(15 downto 0) & paddings(15 downto 0); end if;
if (shamt(3) = '1') then result := result(23 downto 0) & paddings( 7 downto 0); end if;
if (shamt(2) = '1') then result := result(27 downto 0) & paddings( 3 downto 0); end if;
if (shamt(1) = '1') then result := result(29 downto 0) & paddings( 1 downto 0); end if;
if (shamt(0) = '1') then result := result(30 downto 0) & paddings( 0 ); end if;
return result;
end;
 
END;
 
FUNCTION shift_right(value: std_logic_vector(31 DOWNTO 0); shamt: std_logic_vector(4 DOWNTO 0); padding: std_logic) RETURN std_logic_vector IS
VARIABLE result: std_logic_vector(31 DOWNTO 0);
VARIABLE paddings: std_logic_vector(15 DOWNTO 0);
BEGIN
 
paddings := (OTHERS => padding);
function shift_right(value: std_logic_vector(31 downto 0); shamt: std_logic_vector(4 downto 0); padding: std_logic) return std_logic_vector is
variable result: std_logic_vector(31 downto 0);
variable paddings: std_logic_vector(15 downto 0);
begin
paddings := (others => padding);
result := value;
IF (shamt(4) = '1') THEN result := paddings(15 DOWNTO 0) & result(31 DOWNTO 16); END IF;
IF (shamt(3) = '1') THEN result := paddings( 7 DOWNTO 0) & result(31 DOWNTO 8); END IF;
IF (shamt(2) = '1') THEN result := paddings( 3 DOWNTO 0) & result(31 DOWNTO 4); END IF;
IF (shamt(1) = '1') THEN result := paddings( 1 DOWNTO 0) & result(31 DOWNTO 2); END IF;
IF (shamt(0) = '1') THEN result := paddings( 0 ) & result(31 DOWNTO 1); END IF;
RETURN result;
if (shamt(4) = '1') then result := paddings(15 downto 0) & result(31 downto 16); end if;
if (shamt(3) = '1') then result := paddings( 7 downto 0) & result(31 downto 8); end if;
if (shamt(2) = '1') then result := paddings( 3 downto 0) & result(31 downto 4); end if;
if (shamt(1) = '1') then result := paddings( 1 downto 0) & result(31 downto 2); end if;
if (shamt(0) = '1') then result := paddings( 0 ) & result(31 downto 1); end if;
return result;
end;
 
END;
 
FUNCTION multiply(a, b: std_logic_vector) RETURN std_logic_vector IS
VARIABLE x: std_logic_vector (a'length + b'length - 1 DOWNTO 0);
BEGIN
function multiply(a, b: std_logic_vector) return std_logic_vector is
variable x: std_logic_vector (a'length + b'length - 1 downto 0);
begin
x := std_logic_vector(signed(a) * signed(b));
RETURN x(31 DOWNTO 0);
END;
return x(31 downto 0);
end;
 
FUNCTION sign_extend(value: std_logic_vector; fill: std_logic; size: positive) RETURN std_logic_vector IS
VARIABLE a: std_logic_vector (size - 1 DOWNTO 0);
BEGIN
a(size - 1 DOWNTO value'length) := (OTHERS => fill);
a(value'length - 1 DOWNTO 0) := value;
function sign_extend(value: std_logic_vector; fill: std_logic; size: positive) return std_logic_vector is
variable a: std_logic_vector (size - 1 downto 0);
begin
a(size - 1 downto value'length) := (others => fill);
a(value'length - 1 downto 0) := value;
return a;
END;
end;
 
FUNCTION add(a, b : std_logic_vector; ci: std_logic) RETURN std_logic_vector IS
VARIABLE x : std_logic_vector(a'length + 1 DOWNTO 0);
BEGIN
x := (OTHERS => '0');
IF notx (a & b & ci) THEN
function add(a, b : std_logic_vector; ci: std_logic) return std_logic_vector is
variable x : std_logic_vector(a'length + 1 downto 0);
begin
x := (others => '0');
if notx (a & b & ci) then
x := std_logic_vector(signed('0' & a & '1') + signed('0' & b & ci));
END IF;
RETURN x(a'length + 1 DOWNTO 1);
END;
end if;
return x(a'length + 1 downto 1);
end;
 
FUNCTION increment(a : std_logic_vector) RETURN std_logic_vector IS
VARIABLE x : std_logic_vector(a'length-1 DOWNTO 0);
BEGIN
x := (OTHERS => '0');
IF notx (a) THEN
function increment(a : std_logic_vector) return std_logic_vector is
variable x : std_logic_vector(a'length-1 downto 0);
begin
x := (others => '0');
if notx (a) then
x := std_logic_vector(signed(a) + 1);
END IF;
RETURN x;
END;
end if;
return x;
end;
 
END std_Pkg;
end std_Pkg;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.