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

Subversion Repositories tinycpu

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /tinycpu
    from Rev 17 to Rev 18
    Reverse comparison

Rev 17 → Rev 18

/trunk/testbench/memory_tb.vhd
11,13 → 11,12
component memory
port(
Address: in std_logic_vector(15 downto 0); --memory address
Write: in std_logic; --write or read
UseTopBits: in std_logic; --if 1, top 8 bits of data is ignored and not written to memory
Address: in std_logic_vector(15 downto 0); --memory address (in bytes)
WriteWord: in std_logic; --if set, will write a full 16-bit word instead of a byte. Address must be aligned to 16-bit address. (bottom bit must be 0)
WriteEnable: in std_logic;
Clock: in std_logic;
DataIn: in std_logic_vector(15 downto 0);
DataOut: out std_logic_vector(15 downto 0);
Reset: in std_logic
DataOut: out std_logic_vector(15 downto 0)
);
end component;
24,10 → 23,9
 
--Inputs
signal Address: std_logic_vector(15 downto 0) := (others => '0');
signal Write: std_logic := '0';
signal UseTopBits: std_logic := '0';
signal WriteWord: std_logic := '0';
signal WriteEnable: std_logic := '0';
signal DataIn: std_logic_vector(15 downto 0) := (others => '0');
signal Reset: std_logic := '0';
 
--Outputs
signal DataOut: std_logic_vector(15 downto 0);
40,12 → 38,11
-- Instantiate the Unit Under Test (UUT)
uut: memory PORT MAP (
Address => Address,
Write => Write,
UseTopBits => UseTopBits,
WriteWord => WriteWord,
WriteEnable => WriteEnable,
Clock => Clock,
DataIn => DataIn,
DataOut => DataOut,
Reset => Reset
DataOut => DataOut
);
 
-- Clock process definitions
62,75 → 59,61
stim_proc: process
variable err_cnt: integer :=0;
begin
-- hold reset state for 100 ns.
Reset <= '1';
wait for 100 ns;
wait for 50 ns;
 
wait for clock_period*10;
--case 1
Reset <= '0';
Write <= '0';
Address <= x"0000";
WriteWord <= '1';
WriteEnable <='1';
DataIn <= x"1234";
wait for 10 ns;
Address <= "0000000000001000";
DataIn <= "1000000000001000";
Write <= '1';
UseTopBits <= '1';
WriteWord <= '0';
WriteEnable <= '0';
wait for 10 ns;
Write <= '0';
assert (DataOut = x"1234") report "Basic storage failure" severity error;
Address <= x"0022";
WriteWord <= '1';
WriteEnable <= '1';
DataIn <= x"5215";
wait for 10 ns;
assert (DataOut="1000000000001000") report "Storage error case 1" severity error;
 
--case 2
Address <= "0000000000001100";
DataIn <= "1000000000001100";
Write <= '1';
UseTopBits <= '1';
assert (DataOut = x"1234") report "no-change block ram failure" severity error;
WriteWord <= '0';
WriteEnable <= '0';
Address <= x"0000";
wait for 10 ns;
Write <= '0';
assert( DataOut = x"1234") report "Memory retention failure" severity error;
Address <= x"0022";
wait for 10 ns;
assert (DataOut="1000000000001100") report "memory selection error case 2" severity error;
 
-- case 3
Address <= "0000000000001000";
wait for 10 ns;
assert (DataOut="1000000000001000") report "memory retention error case 3" severity error;
assert( DataOut = x"5215") report "memory timing is too slow" severity error;
--case 4
Address <= x"0000";
Write <= '1';
DataIn <= x"FFCC";
Address <= x"0010";
WriteWord <= '1';
WriteEnable <= '1';
DataIn <= x"1234";
wait for 10 ns;
UseTopBits <= '0';
DataIn <= x"F0C0";
WriteWord <= '0';
WriteEnable <= '0';
Address <= x"0011";
wait for 10 ns;
UseTopBits <='1';
Write <= '0';
assert (DataOut = x"0012") report "unaligned 8-bit memory read is wrong" severity error;
WriteWord <='0';
WriteEnable <= '1';
DataIn <= x"0056";
wait for 10 ns;
assert (DataOut=x"FFC0") report "ignore top bits error case 4" severity error;
--case 5
--Address <= x"FFFF";
--Write <= '0';
--wait for 10 ns;
--assert (DataOut=x"FFC0") report "memory out of range error case 5" severity error;
--case 6 (fetch and store practical)
Address <= x"0012";
WriteEnable <= '0';
wait for 10 ns;
Address <= x"0000";
wait for 5 ns;
assert(DataOut=x"FFC0") report "practical fail 1" severity error;
Address <= x"00FF";
Write <= '1';
DataIn <= x"1234";
wait for 5 ns;
Write <= '0';
assert (DataOut = x"0056") report "unaligned 8 bit memory write and then read is wrong" severity error;
Address <= x"0010";
wait for 10 ns;
assert(DataOut=x"1234") report "practical fail 2" severity error;
assert (DataOut = x"5634") report "aligned memory read after unaligned write is wrong" severity error;
WriteEnable <= '1';
DataIn <= x"0078";
wait for 10 ns;
WriteEnable <= '0';
wait for 10 ns;
assert (DataOut = x"5678") report "aligned 8-bit memory write is wrong" severity error;
 
 
 
assert false
report "Testbench of memory completed successfully!"
severity note;
/trunk/testbench/fetch_tb.vhd
60,7 → 60,7
variable err_cnt: integer :=0;
begin
-- hold reset state for 20 ns.
wait for 20 ns;
wait for 10 ns;
 
--wait for clock_period*10;
Enable<= '1';
/trunk/src/memory.vhd
1,63 → 1,109
--RAM module
--4096*8 bit file
--simultaneous write/read support
--16 bit or 8 bit data bus
--16 bit address bus
--On Reset, will load a "default" RAM image
--Memory management component
--By having this separate, it should be fairly easy to add RAMs or ROMs later
--This basically lets the CPU not have to worry about how memory "Really" works
--currently just one RAM. 1024 byte blockram.vhd mapped as 0 - 1023
 
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_arith.all;
use IEEE.NUMERIC_STD.ALL;
use ieee.std_logic_unsigned.all;
 
 
 
entity memory is
port(
Address: in std_logic_vector(15 downto 0); --memory address
Write: in std_logic; --write or read
UseTopBits: in std_logic; --if 1, top 8 bits of data is ignored and not written to memory
Address: in std_logic_vector(15 downto 0); --memory address (in bytes)
WriteWord: in std_logic; --if set, will write a full 16-bit word instead of a byte. Address must be aligned to 16-bit address. (bottom bit must be 0)
WriteEnable: in std_logic;
Clock: in std_logic;
DataIn: in std_logic_vector(15 downto 0);
DataOut: out std_logic_vector(15 downto 0);
Reset: in std_logic
DataOut: out std_logic_vector(15 downto 0)
-- Reset: in std_logic
--RAM/ROM interface (RAMA is built in to here
--RAMBDataIn: out std_logic_vector(15 downto 0);
--RAMBDataOut: in std_logic_vector(15 downto 0);
--RAMBAddress: out std_logic_vector(15 downto 0);
--RAMBWriteEnable: out std_logic_vector(1 downto 0);
);
end memory;
 
architecture Behavioral of memory is
constant BUSSIZE : integer := 8;
type memorytype is array(0 to integer((2**BUSSIZE))) of std_logic_vector(7 downto 0);
signal mem: memorytype;
 
component blockram
port(
Address: in std_logic_vector(7 downto 0); --memory address
WriteEnable: in std_logic_vector(1 downto 0); --write or read
Enable: in std_logic;
Clock: in std_logic;
DataIn: in std_logic_vector(15 downto 0);
DataOut: out std_logic_vector(15 downto 0)
);
end component;
 
constant R1START: integer := 0;
constant R1END: integer := 1023;
signal addr: std_logic_vector(15 downto 0) := (others => '0');
signal R1addr: std_logic_vector(7 downto 0);
signal we: std_logic_vector(1 downto 0);
signal datawrite: std_logic_vector(15 downto 0);
signal dataread: std_logic_vector(15 downto 0);
--signal en: std_logic;
signal R1we: std_logic_vector(1 downto 0);
signal R1en: std_logic;
signal R1in: std_logic_vector(15 downto 0);
signal R1out: std_logic_vector(15 downto 0);
begin
 
writemem: process(Reset,Write, Address, UseTopBits, Clock)
variable addr: integer range 0 to (2**BUSSIZE)-1 := 0;
R1: blockram port map (R1addr, R1we, R1en, Clock, R1in, R1out);
addrwe: process(Address, WriteWord, WriteEnable, DataIn)
begin
addr := conv_integer(Address(BUSSIZE-1 downto 0));
if(rising_edge(Clock)) then
if(Reset ='1') then
--mem <= (others => "00000000");
elsif( Write='1') then
mem(addr) <= DataIn(7 downto 0);
if(UseTopBits='1') then
mem(addr+1) <= DataIn(15 downto 8);
addr <= Address(15 downto 1) & '0';
if WriteEnable='1' then
if WriteWord='1' then
we <= "11";
datawrite <= DataIn;
else
if Address(0)='0' then
we <= "01";
datawrite <= x"00" & DataIn(7 downto 0); --not really necessary
else
we <= "10";
datawrite <= DataIn(7 downto 0) & x"00";
end if;
end if;
else
we <= "00";
end if;
end process;
readmem: process(Reset,Address,Write,Clock)
variable addr: integer range 0 to (2**BUSSIZE)-1 := 0;
variable addr2: integer range 0 to (2**BUSSIZE)-1 := 0; -- for second part
assignram: process (we, datawrite, addr, r1out)
variable tmp: integer;
variable found: boolean := false;
begin
addr := conv_integer(Address(BUSSIZE-1 downto 0));
addr2 := conv_integer(Address(BUSSIZE-1 downto 0));
if(Reset='1') then
DataOut <= (others => '0');
elsif(Write='0') then
DataOut <= mem(addr+1) & mem(addr);
else
DataOut <= (others => '0');
tmp := to_integer(unsigned(addr));
if tmp >= R1START and tmp <= R1END then
--map all to R1
found := true;
R1en <= '1';
R1we <= we;
R1in <= datawrite;
dataread <= R1out;
R1addr <= addr(8 downto 1);
else
R1en <= '0';
R1we <= "00";
R1in <= x"0000";
R1addr <= x"00";
dataread <= x"0000";
end if;
end process;
 
readdata: process(Address, dataread)
begin
if Address(0) = '0' then
DataOut <= dataread;
else
DataOut <= x"00" & dataread(15 downto 8);
end if;
end process;
end Behavioral;

powered by: WebSVN 2.1.0

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