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

Subversion Repositories tinycpu

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 22 to Rev 23
    Reverse comparison

Rev 22 → Rev 23

/tinycpu/trunk/testbench/top_tb.vhd
0,0 → 1,121
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
ENTITY top_tb IS
END top_tb;
ARCHITECTURE behavior OF top_tb IS
-- Component Declaration for the Unit Under Test (UUT)
 
component top is
port(
Reset: in std_logic;
Hold: in std_logic;
HoldAck: out std_logic;
Clock: in std_logic;
DMA: in std_logic; --when high, Address, WriteEnable, and Data are connected to memory
Address: in std_logic_vector(15 downto 0); --memory address (in bytes)
WriteEnable: in std_logic;
Data: inout std_logic_vector(15 downto 0);
--debug ports
DebugR0: out std_logic_vector(7 downto 0)
);
end component;
 
signal Reset:std_logic:='0';
signal Hold: std_logic:='0';
signal HoldAck: std_logic;
signal DMA: std_logic:='0'; --when high, Address, WriteEnable, and Data are connected to memory
signal Address: std_logic_vector(15 downto 0):=x"0000"; --memory address (in bytes)
signal WriteEnable: std_logic:='0';
signal Data: std_logic_vector(15 downto 0):=x"0000";
--debug ports
signal DebugR0: std_logic_vector(7 downto 0);
 
signal Clock: std_logic;
constant clock_period : time := 10 ns;
BEGIN
 
-- Instantiate the Unit Under Test (UUT)
uut: top PORT MAP (
Reset => Reset,
Hold => Hold,
HoldAck => HoldAck,
Clock => Clock,
DMA => DMA,
Address => Address,
WriteEnable => WriteEnable,
Data => Data,
DebugR0 => DebugR0
);
 
-- Clock process definitions
clock_process :process
begin
Clock <= '0';
wait for clock_period/2;
Clock <= '1';
wait for clock_period/2;
end process;
 
-- Stimulus process
stim_proc: process
variable err_cnt: integer :=0;
begin
-- hold reset state for 100 ns.
Reset <= '1';
wait for 20 ns;
Hold <= '1';
wait for 10 ns;
assert (HoldAck ='1') report "HoldAck not becoming high" severity error;
--load memory image
DMA <= '1';
WriteEnable <= '1';
Address <= x"0100";
Data <= x"0057";
wait for 10 ns;
Address <= x"0102";
Data <= x"00F1";
wait for 10 ns;
Address <= x"0104";
Data <= x"00FF";
wait for 10 ns;
Address <= x"0106";
Data <= x"0063";
wait for 10 ns;
DMA <= '0';
wait for 10 ns;
Hold <= '0';
wait for 10 ns;
--start the processor
Reset <= '0';
wait for 30 ns; --wait 3 clock cycles for CPU to execute first instruction
wait for 20 ns; --wait 2 clock cycle for first instruction decode and register write to complete
assert(Debugr0 = x"57") report "R0 is not loaded properly for first instruction" severity error;
wait for 10 ns;
assert(DebugR0 = x"F1") report "R0 is not loaded properly for second instruction" severity error;
 
 
 
 
assert false
report "Testbench of top completed successfully!"
severity note;
wait;
 
-- insert stimulus here
 
wait;
end process;
 
 
END;
/tinycpu/trunk/src/top.vhd
0,0 → 1,112
--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.NUMERIC_STD.ALL;
 
 
 
entity top is
port(
Reset: in std_logic;
Hold: in std_logic;
HoldAck: out std_logic;
Clock: in std_logic;
DMA: in std_logic; --when high, Address, WriteEnable, and Data are connected to memory
Address: in std_logic_vector(15 downto 0); --memory address (in bytes)
WriteEnable: in std_logic;
Data: inout std_logic_vector(15 downto 0);
--debug ports
DebugR0: out std_logic_vector(7 downto 0)
);
end top;
 
architecture Behavioral of top is
 
component memory is
port(
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)
);
end component;
 
component core is
port(
--memory interface
MemAddr: out std_logic_vector(15 downto 0); --memory address (in bytes)
MemWW: out std_logic; --memory writeword
MemWE: out std_logic; --memory writeenable
MemIn: in std_logic_vector(15 downto 0);
MemOut: out std_logic_vector(15 downto 0);
--general interface
Clock: in std_logic;
Reset: in std_logic; --When this is high, CPU will reset within 1 clock cycles.
--Enable: in std_logic; --When this is high, the CPU executes as normal, when low the CPU stops at the next clock cycle(maintaining all state)
Hold: in std_logic; --when high, CPU pauses execution and places Memory interfaces into high impendance state so the memory can be used by other components
HoldAck: out std_logic; --when high, CPU acknowledged hold and buses are in high Z
--todo: port interface
 
--debug ports:
DebugIR: out std_logic_vector(15 downto 0); --current instruction
DebugIP: out std_logic_vector(7 downto 0); --current IP
DebugCS: out std_logic_vector(7 downto 0); --current code segment
DebugTR: out std_logic; --current value of TR
DebugR0: out std_logic_vector(7 downto 0)
);
end component;
signal cpuaddr: std_logic_vector(15 downto 0);
signal cpuww: std_logic;
signal cpuwe: std_logic;
signal cpumemin: std_logic_vector(15 downto 0);
signal cpumemout: std_logic_vector(15 downto 0);
signal debugir: std_logic_vector(15 downto 0);
signal debugip: std_logic_vector(7 downto 0);
signal debugcs: std_logic_vector(7 downto 0);
signal debugtr: std_logic;
 
signal MemAddress: std_logic_vector(15 downto 0); --memory address (in bytes)
signal MemWriteWord: 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)
signal MemWriteEnable: std_logic;
signal MemDataIn: std_logic_vector(15 downto 0);
signal MemDataOut: std_logic_vector(15 downto 0);
begin
cpu: core port map (
MemAddr => cpuaddr,
MemWW => cpuww,
MemWE => cpuwe,
MemIn => cpumemin,
MemOut => cpumemout,
Clock => Clock,
Reset => Reset,
Hold => Hold,
HoldAck => HoldAck,
DebugIR => DebugIR,
DebugIP => DebugIP,
DebugCS => DebugCS,
DebugTR => DebugTR,
DebugR0 => DebugR0
);
mem: memory port map(
Address => MemAddress,
WriteWord => MemWriteWord,
WriteEnable => MemWriteEnable,
Clock => Clock,
DataIn => MemDataIn,
DataOut => MemDataOut
);
 
MemAddress <= cpuaddr when DMA='0' else Address;
MemWriteWord <= cpuww when DMA='0' else '1';
MemWriteEnable <= cpuwe when DMA='0' else WriteEnable;
MemDataIn <= cpumemout when DMA='0' else Data when WriteEnable='1' else "ZZZZZZZZZZZZZZZZ";
cpumemin <= MemDataOut;
Data <= MemDataOut when DMA='1' and WriteEnable='0' else "ZZZZZZZZZZZZZZZZ";
 
end Behavioral;
/tinycpu/trunk/src/core.vhd
84,6 → 84,7
ResetProcessor,
FirstFetch1, --the fetcher needs two clock cycles to catch up
FirstFetch2,
Firstfetch3,
Execute,
WaitForMemory,
HoldMemory
204,10 → 205,7
elsif state=FirstFetch1 then --we have to let IR get loaded before we can execute.
--regWE <= (others => '0');
fetchEN <= '1'; --already enabled, but anyway
regWE <= (others => '0');
state <= FirstFetch2;
elsif state=FirstFetch2 then
state <= Execute;
--regWE <= (others => '0');
IPAddend <= x"02";
SPAddend <= x"00"; --no addend unless pushing or popping
RegWE <= (others => '0');
215,6 → 213,12
regWE(REGIP) <= '1';
regWE(REGCS) <= '1';
regIn(REGCS) <= CSCarryOut;
state <= Execute;
elsif state=FirstFetch2 then
state <= FirstFetch3;
elsif state=FirstFetch3 then
state <= Execute;
end if;
 
 

powered by: WebSVN 2.1.0

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