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

Subversion Repositories tinycpu

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /tinycpu/trunk
    from Rev 20 to Rev 21
    Reverse comparison

Rev 20 → Rev 21

/testbench/carryover_tb.vhd
17,10 → 17,19
SegmentIn: in std_logic_vector(7 downto 0);
Addend: in std_logic_vector(7 downto 0); --How much to increase DataIn by (as a signed number). Believe it or not, that's the actual word for what we need.
DataOut: out std_logic_vector(7 downto 0);
SegmentOut: out std_logic_vector(7 downto 0)
SegmentOut: out std_logic_vector(7 downto 0);
Clock: in std_logic
-- Debug: out std_logic_vector(8 downto 0)
);
end component;
component registerfile is
port(
WriteEnable: in regwritetype;
DataIn: in regdatatype;
Clock: in std_logic;
DataOut: out regdatatype
);
end component;
 
--Inputs
32,6 → 41,10
signal DataOut: std_logic_vector(7 downto 0);
signal SegmentOut: std_logic_vector(7 downto 0);
-- signal Debug: std_logic_vector(8 downto 0);
signal regwe: regwritetype;
signal regin: regdatatype;
signal regout: regdatatype;
 
signal Clock: std_logic;
constant clock_period : time := 10 ns;
45,9 → 58,16
Addend => Addend,
SegmentIn => SegmentIn,
DataOut => DataOut,
SegmentOut => SegmentOut
SegmentOut => SegmentOut,
Clock => Clock
-- Debug => Debug
);
regfile: registerfile port map(
WriteEnable => regwe,
DataIn => regin,
Clock => Clock,
DataOut => regout
);
 
-- Clock process definitions
clock_process :process
98,6 → 118,25
SegmentIn <= x"00";
wait for 10 ns;
assert (SegmentOut=x"00" and DataOut = x"FE") report "Carryover when not appropriate case 1" severity error;
--practical register test
regin(0) <= x"10";
regwe(0) <= '1';
wait for 10 ns;
regwe(0) <= '0';
wait for 10 ns;
regwe(0) <= '1';
DataIn <= regout(0);
Addend <= x"02";
SegmentIn <= x"00";
wait for 10 ns;
regin(0) <= DataOut;
wait for 10 ns;
assert(DataOut = x"12") report "practical fail 1" severity error;
DataIn <= regout(0);
regin(0) <= DataOut;
wait for 10 ns;
assert(DataOut = x"14") report "practical fail 2" severity error;
 
-- summary of testbench
assert false
/testbench/core_tb.vhd
41,11 → 41,11
signal MemWW: std_logic; --memory writeword
signal MemWE: std_logic; --memory writeenable
signal MemOut: std_logic_vector(15 downto 0);
signal MemIn: std_logic_vector(15 downto 0);
signal MemIn: std_logic_vector(15 downto 0):=x"0000";
--general interface
signal Reset: std_logic; --When this is high, CPU will reset within 1 clock cycles.
signal Reset: std_logic:='0'; --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)
signal Hold: std_logic; --when high, CPU pauses execution and places Memory interfaces into high impendance state so the memory can be used by other components
signal Hold: std_logic:='0'; --when high, CPU pauses execution and places Memory interfaces into high impendance state so the memory can be used by other components
signal HoldAck: std_logic; --when high, CPU acknowledged hold and buses are in high Z
--todo: port interface
 
111,7 → 111,7
Reset <= '0';
MemIn <= x"0012"; --mov r0, 0xFF
wait for 10 ns;
wait for 30 ns; --fetcher needs two clock cycles to catch up
assert(MemAddr = x"0100") report "Not fetching from correct start address" severity error;
MemIn <= x"00F1"; --mov r0, 0xF1
wait for 10 ns;
/testbench/fetch_tb.vhd
69,7 → 69,7
Enable <= '1';
AddressIn <= x"1234";
DataIn <= x"5321";
wait for 10 ns;
wait for 10 ns;
assert (IROut = x"5321" and AddressOut = x"1234") report "basic operation failure" severity error;
AddressIn <= x"5121";
/src/core.vhd
60,7 → 60,8
SegmentIn: in std_logic_vector(7 downto 0);
Addend: in std_logic_vector(7 downto 0); --How much to increase DataIn by (as a signed number). Believe it or not, that's the actual word for what we need.
DataOut: out std_logic_vector(7 downto 0);
SegmentOut: out std_logic_vector(7 downto 0)
SegmentOut: out std_logic_vector(7 downto 0);
Clock: in std_logic
);
end component;
component registerfile is
81,7 → 82,8
 
type ProcessorState is (
ResetProcessor,
FirstFetch,
FirstFetch1, --the fetcher needs two clock cycles to catch up
FirstFetch2,
Execute,
WaitForMemory,
HoldMemory
127,11 → 129,12
);
carryovercs: carryover port map(
EnableCarry => CarryCS,
DataIn => regOut(REGIP),
SegmentIn => regOut(REGCS),
DataIn => regIn(REGIP),
SegmentIn => regIn(REGCS),
Addend => IPAddend,
DataOut => IPCarryOut,
SegmentOut => CSCarryOut
SegmentOut => CSCarryOut,
Clock => Clock
);
fetcher: fetch port map(
Enable => fetchEN,
141,7 → 144,7
IROut => IR,
AddressOut => MemAddr --this component supports tristate, so no worries about an intermediate signal
);
fetcheraddress <= regOut(REGCS) & regOut(REGIP);
fetcheraddress <= regIn(REGCS) & regIn(REGIP);
 
 
--opcode shortcuts
160,23 → 163,37
DebugIR <= IR;
 
 
 
states: process(Clock, reset, hold, state)
decode: process(Clock, Hold, state, IR, inreset, reset, regin, regout, IPCarryOut, CSCarryOut)
begin
if rising_edge(Clock) then
 
--states
if reset='1' and hold='0' then
InReset <= '1';
state <= ResetProcessor;
HoldAck <= '0';
CarryCS <= '1';
CarrySS <= '0';
regWE <= (others => '1');
regIn <= (others => "00000000");
regIn(REGCS) <= x"01";
IPAddend <= x"00";
fetchEN <= '1';
--finish up
elsif InReset='1' and reset='0' and Hold='0' then --reset is done, start executing
InReset <= '0';
state <= FirstFetch;
fetchEN <= '1';
state <= FirstFetch1;
elsif Hold = '1' and (state=HoldMemory or state=Execute or state=ResetProcessor) then
--do not hold immediately if waiting on memory or if waiting on the first fetch of an instruction after reset
state <= HoldMemory;
HoldAck <= '1';
FetchEN <= '0';
MemAddr <= "ZZZZZZZZZZZZZZZZ";
MemOut <= "ZZZZZZZZZZZZZZZZ";
MemWE <= 'Z';
MemWW <= 'Z';
elsif Hold='0' and state=HoldMemory then
if reset='1' or InReset='1' then
state <= ResetProcessor;
183,25 → 200,35
else
state <= Execute;
end if;
elsif state=FirstFetch then --we have to let IR get loaded before we can execute.
FetchEN <= '1';
elsif state=FirstFetch1 then --we have to let IR get loaded before we can execute.
--regWE <= (others => '0');
state <= Execute;
fetchEN <= '1'; --already enabled, but anyway
regWE <= (others => '0');
state <= FirstFetch2;
elsif state=FirstFetch2 then
state <= Execute;
IPAddend <= x"02";
SPAddend <= x"00"; --no addend unless pushing or popping
RegWE <= (others => '0');
regIn(REGIP) <= IPCarryOut;
regWE(REGIP) <= '1';
regWE(REGCS) <= '1';
regIn(REGCS) <= CSCarryOut;
end if;
end if;
end process;
decode: process(Clock, Hold, state, IR, inreset)
begin
if rising_edge(Clock) then
 
 
if state=Execute then
fetchEN <= '1';
--reset to "usual"
RegIn(REGIP) <= IPCarryOut;
IPAddend <= x"02";
SPAddend <= x"00"; --no addend unless pushing or popping
RegIn(REGCS) <= CSCarryOut;
RegWE <= (others => '0');
regIn(REGIP) <= IPCarryOut;
regWE(REGIP) <= '1';
regWE(REGCS) <= '1';
regIn(REGCS) <= CSCarryOut;
MemWE <= '0';
MemWW <= '0';
215,26 → 242,11
report "Not implemented" severity error;
--synthesis on
end case;
elsif state=ResetProcessor then
CarryCS <= '1';
CarrySS <= '0';
regWE <= (others => '1');
regIn <= (others => "00000000");
regIn(REGCS) <= x"01";
fetchEN <= '1';
elsif InReset='1' and hold='0' then
fetchEN <= '1';
elsif state=HoldMemory then
FetchEN <= '0';
MemAddr <= "ZZZZZZZZZZZZZZZZ";
MemOut <= "ZZZZZZZZZZZZZZZZ";
MemWE <= 'Z';
MemWW <= 'Z';
elsif state=FirstFetch then
fetchEN <= '1'; --already enabled, but anyway
elsif state=HoldMemory and hold='0' then
fetchEN <= '1';
end if;
 
 
 
 
end if;
end process;
 
/src/fetch.vhd
29,7 → 29,7
begin
process(Clock, AddressIn, DataIn)
begin
if(rising_edge(Clock)) then
--if(rising_edge(Clock)) then
if(Enable='1') then
IR <= DataIn;
AddressOut <= AddressIn;
36,7 → 36,8
else
AddressOut <= "ZZZZZZZZZZZZZZZZ";
end if;
end if;
--end if;
end process;
--AddressOut <= AddressIn when Enable='1' else "ZZZZZZZZZZZZZZZZ";
IROut <= IR;
end Behavioral;
/src/carryover.vhd
10,26 → 10,31
SegmentIn: in std_logic_vector(7 downto 0);
Addend: in std_logic_vector(7 downto 0); --How much to increase DataIn by (as a signed number). Believe it or not, that's the actual word for what we need.
DataOut: out std_logic_vector(7 downto 0);
SegmentOut: out std_logic_vector(7 downto 0)
SegmentOut: out std_logic_vector(7 downto 0);
Clock: in std_logic
-- Debug: out std_logic_vector(8 downto 0)
);
end carryover;
 
architecture Behavioral of carryover is
signal temp: std_logic_vector(8 downto 0);
signal temp: std_logic_vector(8 downto 0) := "000000000";
signal temp2: std_logic_vector(7 downto 0);
begin
--treat as unsigned because it doesn't actually matter for addition and just make carry and borrow correct
process(DataIn, SegmentIn,Addend, EnableCarry)
begin
temp <= std_logic_vector(unsigned('0' & DataIn) + unsigned( Addend));
-- if ('1' and ((not Addend(7)) and DataIn(7) and temp(8)))='1' then
if (EnableCarry and ((not Addend(7)) and DataIn(7) and not temp(8)))='1' then
SegmentOut <= std_logic_vector(unsigned(SegmentIn)+1);
elsif (EnableCarry and (Addend(7) and not DataIn(7) and temp(8)))='1' then
SegmentOut <= std_logic_vector(unsigned(SegmentIn)-1);
else
SegmentOut <= SegmentIn;
end if;
--if rising_edge(Clock) then
temp <= std_logic_vector(unsigned('0' & DataIn) + unsigned( Addend));
-- if ('1' and ((not Addend(7)) and DataIn(7) and temp(8)))='1' then
if (EnableCarry and ((not Addend(7)) and DataIn(7) and not temp(8)))='1' then
SegmentOut <= std_logic_vector(unsigned(SegmentIn)+1);
elsif (EnableCarry and (Addend(7) and not DataIn(7) and temp(8)))='1' then
SegmentOut <= std_logic_vector(unsigned(SegmentIn)-1);
else
SegmentOut <= SegmentIn;
end if;
--end if;
end process;
--Debug <= Temp;
DataOut <= temp(7 downto 0);
/docs/design.md.txt
273,9 → 273,16
Carryover is set on CS and not set on SS. DS and ES is 0. TR is false.
Register bank 0 is selected.
 
Electrical operation:
On power-on, RESET should be high for at least 2 clock cycles. HOLD can optionally be high as well after these two clock cycles.
When HOLD is no longer needed, it should just be turned low and an extra clock cycle should be waited on for it to return to RESET state
When RESET is held low, the processor will execute. It takes 3 clock cycles for the processor to "catch up" to actually executing instructions
 
 
 
 
 
 
Implemented opcode list:
legend:
r = register choice

powered by: WebSVN 2.1.0

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