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 4 to Rev 5
    Reverse comparison

Rev 4 → Rev 5

/tinycpu/trunk/testbench/registerfile_tb.vhd
11,24 → 11,30
component registerfile
port(
Write:in std_logic_vector(7 downto 0); --what should be put into the write register
SelRead1:in std_logic_vector(2 downto 0); --select which register to read
SelRead2: in std_logic_vector(2 downto 0); --select second register to read
SelWrite:in std_logic_vector(2 downto 0); --select which register to write
UseWrite:in std_logic; --if the register should actually be written to
Write1:in std_logic_vector(7 downto 0); --what should be put into the write register
Write2: in std_logic_vector(7 downto 0);
SelRead1:in std_logic_vector(3 downto 0); --select which register to read
SelRead2: in std_logic_vector(3 downto 0); --select second register to read
SelWrite1:in std_logic_vector(3 downto 0); --select which register to write
SelWrite2:in std_logic_vector(3 downto 0);
UseWrite1:in std_logic; --if the register should actually be written to
UseWrite2: in std_logic;
Clock:in std_logic;
Read1:out std_logic_vector(7 downto 0); --register to be read output
Read2:out std_logic_vector(7 downto 0) --register to be read on second output
);
);
end component;
 
--Inputs
signal Write : std_logic_vector(7 downto 0) := (others => '0');
signal SelRead1: std_logic_vector(2 downto 0) := (others => '0');
signal SelRead2: std_logic_vector(2 downto 0) := (others => '0');
signal SelWrite: std_logic_vector(2 downto 0) := (others => '0');
signal UseWrite: std_logic := '0';
signal Write1 : std_logic_vector(7 downto 0) := (others => '0');
signal Write2 : std_logic_vector(7 downto 0) := (others => '0');
signal SelRead1: std_logic_vector(3 downto 0) := (others => '0');
signal SelRead2: std_logic_vector(3 downto 0) := (others => '0');
signal SelWrite1: std_logic_vector(3 downto 0) := (others => '0');
signal SelWrite2: std_logic_vector(3 downto 0) := (others => '0');
signal UseWrite1: std_logic := '0';
signal UseWrite2: std_logic := '0';
 
--Outputs
signal Read1 : std_logic_vector(7 downto 0);
41,11 → 47,14
 
-- Instantiate the Unit Under Test (UUT)
uut: registerfile PORT MAP (
Write => Write,
Write1 => Write1,
Write2 => Write2,
SelRead1 => SelRead1,
SelRead2 => SelRead2,
SelWrite => SelWrite,
UseWrite => UseWrite,
SelWrite1 => SelWrite1,
SelWrite2 => SelWrite2,
UseWrite1 => UseWrite1,
UseWrite2 => UseWrite2,
Clock => Clock,
Read1 => Read1,
Read2 => Read2
71,51 → 80,66
wait for clock_period*10;
 
-- case 1
SelWrite <= "000";
Write <= "11110000";
UseWrite <= '1';
SelWrite1 <= "0000";
Write1 <= "11110000";
UseWrite1 <= '1';
wait for 10 ns;
SelRead1 <= "000";
UseWrite <= '0';
SelRead1 <= "0000";
UseWrite1 <= '0';
wait for 10 ns;
assert (Read1="11110000") report "Storage error case 1" severity error;
if (Read1/="11110000") then
err_cnt:=err_cnt+1;
end if;
 
-- case 2
SelWrite <= "100";
Write <= "11110001";
UseWrite <= '1';
SelWrite1 <= "1000";
Write1 <= "11110001";
UseWrite1 <= '1';
wait for 10 ns;
SelRead1 <= "100";
UseWrite <= '0';
SelRead1 <= "1000";
UseWrite1 <= '0';
wait for 10 ns;
assert (Read1="11110001") report "Storage selector error case 2" severity error;
if (Read1/="11110001") then
err_cnt:=err_cnt+1;
end if;
 
-- case 3
SelRead1 <= "000";
UseWrite <= '0';
SelRead1 <= "0000";
UseWrite1 <= '0';
wait for 10 ns;
assert (Read1="11110000") report "Storage selector(remembering) error case 3" severity error;
if (Read1/="11110000") then
err_cnt:=err_cnt+1;
end if;
--case 4
SelWrite1 <= x"0";
SelWrite2 <= x"1";
Write1 <= x"12";
Write2 <= x"34";
UseWrite1 <= '1';
UseWrite2 <= '1';
wait for 10 ns;
UseWrite1 <= '0';
UseWrite2 <= '0';
SelRead1 <= x"0";
SelRead2 <= x"1";
wait for 10 ns;
assert (Read1=x"12" and Read2=x"34") report "simultaneous write and read error case 4" severity error;
 
SelWrite1 <= x"0";
SelWrite2 <= x"0";
Write1 <= x"ff";
Write2 <= x"00";
UseWrite1 <= '1';
UseWrite2 <= '1';
wait for 10 ns;
SelRead1 <= x"0";
UseWrite1 <= '0';
UseWrite2 <= '0';
wait for 10 ns;
assert (Read1=x"ff") report "dual-write error handling error case 5" severity error;
 
 
 
-- summary of testbench
if (err_cnt=0) then
assert false
report "Testbench of registerfile completed successfully!"
severity note;
else
assert true
report "Something wrong, try again"
severity error;
end if;
assert false
report "Testbench of registerfile completed successfully!"
severity note;
 
wait;
 
-- insert stimulus here
/tinycpu/trunk/src/registerfile.vhd
5,11 → 5,14
 
entity registerfile is
port(
Write:in std_logic_vector(7 downto 0); --what should be put into the write register
SelRead1:in std_logic_vector(2 downto 0); --select which register to read
SelRead2: in std_logic_vector(2 downto 0); --select second register to read
SelWrite:in std_logic_vector(2 downto 0); --select which register to write
UseWrite:in std_logic; --if the register should actually be written to
Write1:in std_logic_vector(7 downto 0); --what should be put into the write register
Write2: in std_logic_vector(7 downto 0);
SelRead1:in std_logic_vector(3 downto 0); --select which register to read
SelRead2: in std_logic_vector(3 downto 0); --select second register to read
SelWrite1:in std_logic_vector(3 downto 0); --select which register to write
SelWrite2:in std_logic_vector(3 downto 0);
UseWrite1:in std_logic; --if the register should actually be written to
UseWrite2: in std_logic;
Clock:in std_logic;
Read1:out std_logic_vector(7 downto 0); --register to be read output
Read2:out std_logic_vector(7 downto 0) --register to be read on second output
17,16 → 20,21
end registerfile;
 
architecture Behavioral of registerfile is
type registerstype is array(0 to 7) of std_logic_vector(7 downto 0);
type registerstype is array(0 to 15) of std_logic_vector(7 downto 0);
signal registers: registerstype;
begin
writereg: process(Write, SelWrite, UseWrite, Clock)
writereg: process(Write1, Write2, SelWrite1, SelWrite2, UseWrite1, UseWrite2, Clock)
begin
if(UseWrite='1') then
if(UseWrite1='1') then
if(rising_edge(clock)) then
registers(conv_integer(SelWrite)) <= Write;
registers(conv_integer(SelWrite1)) <= Write1;
end if;
end if;
if(UseWrite2='1') then
if(rising_edge(clock) and conv_integer(SelWrite1)/=conv_integer(SelWrite2)) then
registers(conv_integer(SelWrite2)) <= Write2;
end if;
end if;
end process;
Read1 <= registers(conv_integer(SelRead1));
Read2 <= registers(conv_integer(SelRead2));
/tinycpu/trunk/docs/design.md.txt
7,7 → 7,8
5. 1 instruction per clock cycle
 
Register list:
r0-r6 general purpose registers
r0-r5 general purpose registers
sp stack pointer (represented as r6)
ip instruction pointer register (represented as r7)
cs, ds, es, ss segment registers (code segment, data segment, extra segment, stack segment)
tr truth register for conditionals
21,7 → 22,7
 
second byte:
first 1 bit: second portion of condition (if not immediate) (1 for only if false)
next 1 bit: unused
next 1 bit: use extra segment
next 3 bits: other register
last 3 bits: extra opcode information or third register. such as for ADD it could be target=source+third_register
 
35,6 → 36,7
2. move [reg], immediate
3. push and move reg, immediate (or call immediate)
4. push immediate
5. jmp immediate
 
groups: (limited to 2 registers and no immediates. each group has 8 opcodes)
group 1:
42,8 → 44,11
move(load) reg,[reg]
out reg1,reg2 (output to port reg1 value reg2)
in reg1,reg2 (input from port reg2 and store in reg1)
pop reg
push reg
move segmentreg,reg
move reg,segmentreg
 
 
group 2:
and reg1,reg2 (reg1=reg1 and reg2)
or reg, reg
61,17 → 66,39
is less than or equal to reg,reg
is equal to reg,reg
is not equal to reg,reg
equals 0 reg
not equals 0 reg
 
group 4:
push segmentreg
pop segmentreg
push and move reg, reg (or call reg)
exchange reg,reg
exchange reg,seg
clear TR
Set TR
 
group 5:
increment reg
decrement reg
far jmp reg1, reg2 (CS=reg1 and IP=reg2)
far call reg1,reg2
far jmp [reg] (first byte is CS, second byte is IP)
push extended segmentreg, reg (equivalent to push seg; push reg)
pop extended segmentreg, reg (equivalent to pop reg; pop seg)
reset processor (will completely reset the processor to starting state, but not RAM or anything else)
 
 
 
3 register instructions:
1. add reg1, reg2, reg3 (reg1=reg2+reg3)
2. sub reg1, reg2, reg3
 
 
opcodes used: 12 of 16. 4 more opcodes available. Decide what to do with the room later.
 
 
 
0 -nop (doesn't do a thing)
1 -move immediate (only uses first byte)
2 -move
97,3 → 124,16
move
add
sub
 
limitations that shouldn't be passed with instructions
* Doing 2 memory references
* pushing a memory reference (equates to 2 memory references)
 
Note it is possible however to read and write 16bits at one time to the memory to consecutive addresses.
 
 
segments:
DS is used in all "normal" memory references
SS is used in all push and pop instructions
ES is used when the ExtraSegment bit is set for either push/pop or normal memory references
CS is only used for fetching instructions

powered by: WebSVN 2.1.0

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