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; |
|
|