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 24 to Rev 25
- ↔ Reverse comparison
Rev 24 → Rev 25
/trunk/testbench/top_tb.vhd
88,6 → 88,8
Address <= x"0106"; |
Data <= x"0063"; |
wait for 10 ns; |
--Address <= x"0108"; |
--wait for 10 ns; |
DMA <= '0'; |
wait for 10 ns; |
Hold <= '0'; |
/trunk/testbench/core_tb.vhd
126,8 → 126,17
MemIn <= x"0020"; --mov r0, 0x20 |
wait for 10 ns; |
assert (MemAddr = x"0152" and DebugIP=x"50") report "fetching is wrong after move to IP" severity error; --DebugIP uses regOut, Fetchaddress uses regIn, so this is correct |
MemIn <= x"0160"; --mov r0,0x60 if TR is set |
wait for 10 ns; --wait until register write happens |
assert(DebugR0 = x"20") report "mov to r0 is wrong after move to IP" severity error; |
MemIn <= x"1050"; --mov [r0], 0x50 (r0 is 0x20) |
wait for 10 ns; |
assert(DebugR0 = x"20" and DebugTR='0') report "moved to r0 conditional thought TR is 0" severity error; |
wait for 10 ns; |
wait for 10 ns; --wait for memory |
assert(MemAddr = x"0020" and MemWE='1' and MemWW='0' and MemOut=x"0050") report "Write to memory doesn't work" severity error; |
wait for 10 ns; |
--wait for 10 ns; --have to wait an extra cycle for memory |
|
-- summary of testbench |
assert false |
/trunk/src/core.vhd
99,6 → 99,9
signal SPAddend: std_logic_vector(7 downto 0); |
signal IPCarryOut: std_logic_vector(7 downto 0); |
signal CSCarryOut: std_logic_vector(7 downto 0); |
signal SPCarryOut: std_logic_vector(7 downto 0); |
signal SSCarryOut: std_logic_vector(7 downto 0); |
|
--register signals |
signal regWE:regwritetype; |
signal regIn: regdatatype; |
106,9 → 109,19
--fetch signals |
signal fetchEN: std_logic; |
signal IR: std_logic_vector(15 downto 0); |
--alu signals |
signal AluOp: std_logic_vector(4 downto 0); |
signal AluIn1: std_logic_vector(7 downto 0); |
signal AluIn2: std_logic_vector(7 downto 0); |
signal AluOut: std_logic_vector(7 downto 0); |
signal TR: std_logic; |
|
--control signals |
signal InReset: std_logic; |
signal OpAddress: std_logic_vector(15 downto 0); --memory address to use for operation of an instruction |
signal OpData: std_logic_vector(15 downto 0); --data to write or will load to here |
signal OpWW: std_logic; |
signal OpWE: std_logic; |
|
--opcode shortcut signals |
signal opmain: std_logic_vector(3 downto 0); |
119,8 → 132,18
signal opreg2: std_logic_vector(2 downto 0); |
signal opreg3: std_logic_vector(2 downto 0); |
signal opseges: std_logic; --use ES segment |
|
signal regbank: std_logic; |
|
signal fetcheraddress: std_logic_vector(15 downto 0); |
|
--temporary signals |
signal tempreg1: std_logic_vector(3 downto 0); |
signal tempreg2: std_logic_vector(3 downto 0); |
signal tempreg3: std_logic_vector(3 downto 0); |
signal FetchMemAddr: std_logic_vector(15 downto 0); |
|
|
begin |
reg: registerfile port map( |
WriteEnable => regWE, |
137,6 → 160,15
SegmentOut => CSCarryOut, |
Clock => Clock |
); |
carryoverss: carryover port map( |
EnableCarry => CarrySS, |
DataIn => regIn(REGSP), |
SegmentIn => RegIn(REGSS), |
Addend => SPAddend, |
DataOut => SPCarryOut, |
SegmentOut => SSCarryOut, |
Clock => Clock |
); |
fetcher: fetch port map( |
Enable => fetchEN, |
AddressIn => fetcheraddress, |
143,11 → 175,21
Clock => Clock, |
DataIn => MemIn, |
IROut => IR, |
AddressOut => MemAddr --this component supports tristate, so no worries about an intermediate signal |
AddressOut => FetchMemAddr |
); |
cpualu: alu port map( |
Op => AluOp, |
DataIn1 => AluIn1, |
DataIn2 => AluIn2, |
DataOut => AluOut, |
TR => TR |
); |
fetcheraddress <= regIn(REGCS) & regIn(REGIP); |
|
|
MemAddr <= OpAddress when state=WaitForMemory else FetchMemAddr; |
MemOut <= OpData when (state=WaitForMemory and OpWE='1') else x"0000"; |
MemWE <= OpWE when state=WaitForMemory else '0'; |
MemWW <= OpWW when state=WaitForMemory else '0'; |
OpData <= MemIn when (state=WaitForMemory and OpWE='0') else "ZZZZZZZZZZZZZZZZ"; |
--opcode shortcuts |
opmain <= IR(15 downto 12); |
opimmd <= IR(7 downto 0); |
162,9 → 204,14
DebugIP <= regOut(REGIP); |
DebugR0 <= regOut(0); |
DebugIR <= IR; |
|
DebugTR <= TR; |
--register addresses with registerbank baked in |
tempreg1 <= ('1' & opreg1) when (regbank='1' and opreg1(2)='0') else '0' & opreg1; |
tempreg2 <= ('1' & opreg2) when (regbank='1' and opreg2(2)='0') else '0' & opreg2; |
tempreg3 <= ('1' & opreg3) when (regbank='1' and opreg3(2)='0') else '0' & opreg3; |
|
|
|
decode: process(Clock, Hold, state, IR, inreset, reset, regin, regout, IPCarryOut, CSCarryOut) |
begin |
if rising_edge(Clock) then |
180,7 → 227,14
regIn <= (others => "00000000"); |
regIn(REGCS) <= x"01"; |
IPAddend <= x"00"; |
SPAddend <= x"00"; |
AluOp <= "10001"; --reset TR in ALU |
regbank <= '0'; |
fetchEN <= '1'; |
OpData <= "ZZZZZZZZZZZZZZZZ"; |
OpAddress <= x"0000"; |
OpWE <= '0'; |
opWW <= '0'; |
--finish up |
elsif InReset='1' and reset='0' and Hold='0' then --reset is done, start executing |
InReset <= '0'; |
219,6 → 273,10
|
elsif state=FirstFetch3 then |
state <= Execute; |
elsif state=WaitForMemory then |
state <= Execute; |
FetchEn <= '1'; |
IpAddend <= x"02"; |
end if; |
|
|
232,22 → 290,32
regWE(REGIP) <= '1'; |
regWE(REGCS) <= '1'; |
regIn(REGCS) <= CSCarryOut; |
regIn(REGSP) <= SPCarryOut; --with addend being 0, it'll just write SP to SP so it won't change, but this makes code easier for me |
regIn(REGSS) <= SSCarryOut; |
regWE(REGSP) <= '1'; |
regWE(REGSS) <= '1'; |
OpAddress <= "ZZZZZZZZZZZZZZZZ"; |
|
MemWE <= '0'; |
MemWW <= '0'; |
|
--actual decoding |
case opmain is |
when "0000" => --mov reg,imm |
--if to_integer(unsigned(opreg1)) = REGIP then |
|
RegIn(to_integer(unsigned(opreg1))) <= opimmd; |
RegWE(to_integer(unsigned(opreg1))) <= '1'; |
when others => |
--synthesis off |
report "Not implemented" severity error; |
--synthesis on |
end case; |
if opcond1='0' or (opcond1='1' and TR='1') then |
case opmain is |
when "0000" => --mov reg,imm |
regIn(to_integer(unsigned(tempreg1))) <= opimmd; |
regWE(to_integer(unsigned(tempreg1))) <= '1'; |
when "0001" => --mov [reg],imm |
OpAddress <= regOut(REGDS) & regOut(to_integer(unsigned(tempreg1))); |
OpWE <= '1'; |
OpData <= x"00" & opimmd; |
OpWW <= '0'; |
state <= WaitForMemory; |
IPAddend <= x"00"; --disable all this because we have to wait a cycle to write memory |
FetchEN <= '0'; |
when others => |
--synthesis off |
report "Not implemented" severity error; |
--synthesis on |
end case; |
end if; |
end if; |
|
|
/trunk/docs/design.md.txt
33,7 → 33,7
second byte: |
first 1 bit: second portion of condition (if not immediate) (1 for only if false) |
next 1 bit: use extra segment |
next 3 bits: other register. If not 3rd register, top bit specifies which register bank, others unused |
next 3 bits: other register. If not 3rd register |
last 3 bits: extra opcode information or third register. such as for ADD it could be target=source+third_register |
|
...or second byte is immediate value |