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 16 to Rev 17
- ↔ Reverse comparison
Rev 16 → Rev 17
/testbench/carryover_tb.vhd
92,8 → 92,13
SegmentIn <= x"00"; |
wait for 10 ns; |
assert (SegmentOut=x"01" and DataOut = x"02") report "Addition Carryover Error" severity error; |
|
DataIn <= x"7F"; |
Addend <= x"7F"; |
SegmentIn <= x"00"; |
wait for 10 ns; |
assert (SegmentOut=x"00" and DataOut = x"FE") report "Carryover when not appropriate case 1" severity error; |
|
|
-- summary of testbench |
assert false |
report "Testbench of carryover completed successfully!" |
/testbench/fetch_tb.vhd
0,0 → 1,102
LIBRARY ieee; |
USE ieee.std_logic_1164.ALL; |
USE ieee.numeric_std.ALL; |
use work.tinycpu.all; |
|
ENTITY fetch_tb IS |
END fetch_tb; |
|
ARCHITECTURE behavior OF fetch_tb IS |
|
-- Component Declaration for the Unit Under Test (UUT) |
|
component fetch is |
port( |
Enable: in std_logic; |
AddressIn: in std_logic_vector(15 downto 0); |
Clock: in std_logic; |
DataIn: in std_logic_vector(15 downto 0); --interface from memory |
IROut: out std_logic_vector(15 downto 0); |
AddressOut: out std_logic_vector(15 downto 0) --interface to memory |
); |
end component; |
|
|
|
signal Enable: std_logic := '0'; |
signal AddressIn: std_logic_vector(15 downto 0) := x"0000"; |
signal DataIn: std_logic_vector(15 downto 0) := x"0000"; |
|
signal IROut: std_logic_vector(15 downto 0); |
signal AddressOut: std_logic_vector(15 downto 0); |
|
signal Clock: std_logic; |
constant clock_period : time := 10 ns; |
|
BEGIN |
|
-- Instantiate the Unit Under Test (UUT) |
uut: fetch PORT MAP ( |
Enable => Enable, |
AddressIn => AddressIn, |
Clock => Clock, |
DataIn => DataIn, |
IROut => IROut, |
AddressOut => AddressOut |
); |
|
-- 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 20 ns. |
wait for 20 ns; |
|
--wait for clock_period*10; |
Enable<= '1'; |
wait for 10 ns; |
|
Enable <= '1'; |
AddressIn <= x"1234"; |
DataIn <= x"5321"; |
wait for 10 ns; |
assert (IROut = x"5321" and AddressOut = x"1234") report "basic operation failure" severity error; |
|
AddressIn <= x"5121"; |
DataIn <= x"1234"; |
wait for 5 ns; |
assert (IROut = x"5321" and AddressOut = x"1234") report "Timing of latching is too early" severity error; |
wait for 5 ns; |
assert (IROut = x"1234" and AddressOut =x"5121") report "basic operation failure 2" severity error; |
|
|
AddressIn <= x"4278"; |
DataIn <= x"5213"; |
Enable <= '0'; |
wait for 10 ns; |
assert (IROut = x"1234" and AddressOut = "ZZZZZZZZZZZZZZZZ") report "Latching doesn't work on disable" severity error; |
|
-- summary of testbench |
assert false |
report "Testbench of fetch completed successfully!" |
severity note; |
|
wait; |
|
-- insert stimulus here |
|
wait; |
end process; |
|
|
END; |
/src/fetch.vhd
0,0 → 1,42
--This component interfaces with the memory controller and fetches the next instruction according to IP and CS |
--Each instruction is 16 bits. |
|
--How it works: IROut keeps the instruction that was featched in the "last" clock cycle. |
--What is basically required is that AddressIn must be the value that CS:IP "will be" in the next clock cycle |
--This can cause some (in my opinion) odd logic at times, but should not have any problems synthesizing |
|
|
|
|
library IEEE; |
use IEEE.STD_LOGIC_1164.ALL; |
use IEEE.NUMERIC_STD.ALL; |
use work.tinycpu.all; |
|
entity fetch is |
port( |
Enable: in std_logic; |
AddressIn: in std_logic_vector(15 downto 0); |
Clock: in std_logic; |
DataIn: in std_logic_vector(15 downto 0); --interface from memory |
IROut: out std_logic_vector(15 downto 0); |
AddressOut: out std_logic_vector(15 downto 0) --interface to memory |
); |
end fetch; |
|
architecture Behavioral of fetch is |
signal IR: std_logic_vector(15 downto 0); |
begin |
process(Clock, AddressIn, DataIn) |
begin |
if(rising_edge(Clock)) then |
if(Enable='1') then |
IR <= DataIn; |
AddressOut <= AddressIn; |
else |
AddressOut <= "ZZZZZZZZZZZZZZZZ"; |
end if; |
end if; |
end process; |
IROut <= IR; |
end Behavioral; |
/docs/design.md.txt
46,7 → 46,7
2. move [reg], immediate |
3. push and move reg, immediate (or call immediate) |
4. push immediate |
5. mov (relative) immediate |
5. move (relative) reg, immediate |
|
|
groups: (limited to 2 registers and no immediates. each group has 8 opcodes) |
105,7 → 105,7
push extended reg, reg |
pop extended reg,reg |
enable carryover seg |
disable CS carryover seg |
disable carryover seg |
mov relative reg, reg |
exchange reg, reg |
|
114,8 → 114,16
2. sub reg1, reg2, reg3 |
|
|
opcodes used: 12 of 16. 4 more opcodes available. Decide what to do with the room later. |
opcodes used: 13 of 16. 3 more opcodes available. Decide what to do with the room later. |
|
Possible canidates for opcode compression include |
* Push immediate (room for 3 sub-opcodes) |
* push and pop reg (room for 7 sub-opcodes each) |
* equals 0 and not equals 0 (room for 7 sub-opcodes each) |
* Set TR and Reset TR (room for 64 opcodes each) |
* increment and decrement reg (room for 7 opcodes each) |
* enable and disable carry over (room for 7 opcodes each) |
* set register bank 0 and 1 (room for 64 opcodes each) |
|
|
0 -nop (doesn't do a thing) |
161,8 → 169,14
In order to overcome the limitations of only having a 256 byte segment, there is a workaround option to "pretend" that IP is a 16 bit register. |
When CS carryover is enabled, when IP rollover from 255 to 0 or whatever, CS will be incremented. This makes it so that if you start at address 0:0. |
you can continue as far as needed into the address space without having to do ugly far jumps at each of the borders. |
Carryover can only be done on CS and SS. The required circuitry is not implemented for DS or ES due to an extreme level of complexity required for it, also |
it would only lead to unncessarily complex code |
|
Also of note is that `move relative` implements a "carryover" component. This component will work on either IP or SP, and uses CS and SS respectively. |
If used on other registers, there will be no carry over functionality, though it can be used as an easy way to add or subtract an immediate from a register. |
|
|
|
States needed: |
0. reset |
1. decode current instruction (All without memory capable within 1 clock cycle) |