Upload
others
View
11
Download
0
Embed Size (px)
Citation preview
Procesador Mínimo. Completo.
-- MEMORY INDEPENDENT FROM CLK)
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.std_logic_unsigned.ALL;
ENTITY AddressLogic IS
PORT (
PCside, Rside : IN std_logic_vector (15 DOWNTO 0);
Iside : IN std_logic_vector (7 DOWNTO 0);
ALout : OUT std_logic_vector (15 DOWNTO 0);
ResetPC, PCplusI, PCplus1, RplusI, Rplus0 : IN std_logic
);
END AddressLogic;
ARCHITECTURE dataflow OF AddressLogic IS
CONSTANT one : std_logic_vector (4 DOWNTO 0) := "10000";
CONSTANT two : std_logic_vector (4 DOWNTO 0) := "01000";
CONSTANT three : std_logic_vector (4 DOWNTO 0) := "00100";
CONSTANT four : std_logic_vector (4 DOWNTO 0) := "00010";
CONSTANT five : std_logic_vector (4 DOWNTO 0) := "00001";
BEGIN
PROCESS (PCside, Rside, Iside, ResetPC, PCplusI, PCplus1, RplusI, Rplus0)
VARIABLE temp : std_logic_vector (4 DOWNTO 0);
BEGIN
temp := (ResetPC & PCplusI & PCplus1 & RplusI & Rplus0 );
CASE temp IS
WHEN one => ALout <= (OTHERS=>'0');
WHEN two => ALout <= PCside + Iside;
WHEN three => ALout <= PCside + 1;
WHEN four => ALout <= Rside + Iside;
WHEN five => ALout <= Rside;
WHEN OTHERS => ALout <= PCside;
END CASE;
END PROCESS;
END dataflow;
------------------------------------------------
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.std_logic_unsigned.ALL;
ENTITY ProgramCounter IS
PORT (
EnablePC : IN std_logic;
input : IN std_logic_vector (15 DOWNTO 0);
clk : IN std_logic;
output : OUT std_logic_vector (15 DOWNTO 0)
);
END ProgramCounter;
ARCHITECTURE dataflow OF ProgramCounter IS
BEGIN
PROCESS (clk)
BEGIN
IF (clk = '1') THEN
IF (EnablePC = '1') THEN
output <= input;
END IF;
END IF;
END PROCESS;
END dataflow;
--------------------------------------------------------
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.std_logic_unsigned.ALL;
ENTITY AddressingUnit IS
PORT (
Rside : IN std_logic_vector (15 DOWNTO 0);
Iside : IN std_logic_vector (7 DOWNTO 0);
Address : OUT std_logic_vector (15 DOWNTO 0);
clk, ResetPC, PCplusI, PCplus1, RplusI, Rplus0, EnablePC : IN std_logic
);
END AddressingUnit;
ARCHITECTURE dataflow OF AddressingUnit IS
COMPONENT pc
PORT (
EnablePC : IN std_logic;
input : IN std_logic_vector (15 DOWNTO 0);
clk : IN std_logic;
output : OUT std_logic_vector (15 DOWNTO 0)
);
END COMPONENT;
FOR ALL : pc USE ENTITY WORK.ProgramCounter (dataflow);
COMPONENT al
PORT (
PCside, Rside : IN std_logic_vector (15 DOWNTO 0);
Iside : IN std_logic_vector (7 DOWNTO 0);
ALout : OUT std_logic_vector (15 DOWNTO 0);
ResetPC, PCplusI, PCplus1, RplusI, Rplus0 : IN std_logic
);
END COMPONENT;
FOR ALL : al USE ENTITY WORK.AddressLogic (dataflow);
SIGNAL pcout : std_logic_vector (15 DOWNTO 0);
SIGNAL AddressSignal : std_logic_vector (15 DOWNTO 0);
BEGIN
Address <= AddressSignal;
l1 : pc PORT MAP (EnablePC, AddressSignal, clk, pcout);
l2 : al PORT MAP (pcout, Rside, Iside, AddressSignal, ResetPC, PCplusI, PCplus1, RplusI, Rplus0);
END dataflow;
--------------------------------------------------
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.std_logic_unsigned.ALL;
ENTITY InstrunctionRegister IS
PORT (
input : IN std_logic_vector (15 DOWNTO 0);
IRload, clk : IN std_logic;
output : OUT std_logic_vector (15 DOWNTO 0)
);
END InstrunctionRegister;
ARCHITECTURE dataflow OF InstrunctionRegister IS
BEGIN
PROCESS (clk)
BEGIN
IF (clk = '1') THEN
IF (IRload = '1') THEN
output <= input;
END IF;
END IF;
END PROCESS;
END dataflow;
--------------------------------------------
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.std_logic_unsigned.ALL;
ENTITY WindowPointer IS
PORT (
input : IN std_logic_vector (5 DOWNTO 0);
clk, WPreset, WPadd : IN std_logic;
output : OUT std_logic_vector (5 DOWNTO 0)
);
END WindowPointer;
ARCHITECTURE dataflow OF WindowPointer IS
SIGNAL outputSignal : std_logic_vector (5 DOWNTO 0);
BEGIN
PROCESS (clk)
BEGIN
IF (clk = '1') THEN
IF (WPreset = '1') THEN
outputSignal <= (OTHERS => '0');
ELSIF (WPadd = '1') THEN
outputSignal <= outputSignal + input;
END IF;
END IF;
END PROCESS;
output <= outputSignal;
END dataflow;
------------------------------------------
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.std_logic_unsigned.ALL;
ENTITY RegisterFile IS
PORT (
input : IN std_logic_vector (15 DOWNTO 0);
clk : IN std_logic;
base : IN std_logic_vector (5 DOWNTO 0);
Laddr, Raddr : IN std_logic_vector (1 DOWNTO 0);
RFLwrite, RFHwrite : IN std_logic;
Lout, Rout : OUT std_logic_vector (15 DOWNTO 0)
);
END RegisterFile;
ARCHITECTURE dataflow OF RegisterFile IS
SIGNAL Laddress, Raddress : std_logic_vector (5 DOWNTO 0);
TYPE memType IS ARRAY (0 TO 63) OF std_logic_vector (15 DOWNTO 0);
SIGNAL MemoryFile : memType;
BEGIN
Laddress <= Base + Laddr;
Raddress <= Base + Raddr;
Lout <= MemoryFile (conv_integer(Laddress));
Rout <= MemoryFile (conv_integer(Raddress));
PROCESS (clk)
BEGIN
IF (clk = '1') THEN
IF (RFLwrite = '1') THEN
MemoryFile (CONV_INTEGER (Laddress)) (7 DOWNTO 0) <= input (7 DOWNTO 0);
END IF;
IF (RFHwrite = '1') THEN
MemoryFile (CONV_INTEGER (Laddress)) (15 DOWNTO 8) <= input (15 DOWNTO 8);
END IF;
END IF;
END PROCESS;
END dataflow;
---------------------------------------------------------
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.std_logic_unsigned.ALL;
ENTITY StatusRegister IS
PORT (
Cin, Zin, SRload, clk, Cset, Creset, Zset, Zreset : IN std_logic;
Cout, Zout : OUT std_logic
);
END StatusRegister;
ARCHITECTURE dataflow OF StatusRegister IS
BEGIN
PROCESS (clk)
BEGIN
IF (clk = '1') THEN
IF (SRload = '1') THEN
Cout <= Cin;
Zout <= Zin;
ELSIF (Cset='1') THEN
Cout <= '1';
ELSIF (Creset='1') THEN
Cout <= '0';
ELSIF (Zset='1') THEN
Zout <= '1';
ELSIF (Zreset='1') THEN
Zout <= '0';
END IF;
END IF;
END PROCESS;
END dataflow;
-------------------------------------------
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
ENTITY m1x1 IS
PORT (xi, yi, pi, ci : IN std_logic;
xo, yo, po, co : OUT std_logic);
END m1x1;
ARCHITECTURE bitwise OF m1x1 IS
SIGNAL xy : std_logic;
BEGIN
xy <= xi AND yi;
co <= (pi AND xy) OR (pi AND ci) OR (xy AND ci);
po <= pi XOR xy XOR ci;
xo <= xi;
yo <= yi;
END bitwise;
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
ENTITY mult_8by8 IS
PORT (x, y : IN std_logic_vector (7 DOWNTO 0);
z : OUT std_logic_vector (15 DOWNTO 0));
END mult_8by8;
ARCHITECTURE bitwise OF mult_8by8 IS
COMPONENT m1x1
PORT (xi, yi, pi, ci : IN std_logic;
xo, yo, po, co : OUT std_logic);
END COMPONENT;
TYPE pair IS ARRAY (8 DOWNTO 0, 8 DOWNTO 0) OF std_logic;
SIGNAL xv, yv, cv, pv : pair;
BEGIN
rows : FOR i IN x'RANGE GENERATE
cols : FOR j IN y'RANGE GENERATE
cell : m1x1 PORT MAP (xv (i, j), yv (i, j), pv (i, j+1), cv (i, j), xv (i, j+1), yv (i+1, j), pv (i+1, j), cv (i,
j+1));
END GENERATE;
END GENERATE;
sides : FOR i IN x'RANGE GENERATE
xv (i, 0) <= x (i);
cv (i, 0) <= '0';
pv (0, i+1) <= '0';
pv (i+1, x'LENGTH) <= cv (i, x'LENGTH);
yv (0, i) <= y (i);
z (i) <= pv (i+1, 0);
z (i+x'LENGTH) <= pv (x'LENGTH, i+1);
END GENERATE;
END bitwise;
----------------------------------------------------------
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.std_logic_unsigned.ALL;
ENTITY ArithmeticUnit IS
PORT (
A, B : IN std_logic_vector (15 DOWNTO 0);
B15to0, AandB, AorB, notB, shlB, shrB, AaddB, AsubB, AmulB, AcmpB : IN std_logic;
aluout : OUT std_logic_vector (15 DOWNTO 0);
cin : IN std_logic;
zout, cout : OUT std_logic
);
END ArithmeticUnit;
ARCHITECTURE dataflow OF ArithmeticUnit IS
COMPONENT mult
PORT (
x, y : IN std_logic_vector (7 DOWNTO 0);
z : OUT std_logic_vector (15 DOWNTO 0)
);
END COMPONENT;
FOR ALL : mult USE ENTITY work.mult_8by8 (bitwise);
CONSTANT B15to0H : std_logic_vector (9 DOWNTO 0) := "1000000000";
CONSTANT AandBH : std_logic_vector (9 DOWNTO 0) := "0100000000";
CONSTANT AorBH : std_logic_vector (9 DOWNTO 0) := "0010000000";
CONSTANT notBH : std_logic_vector (9 DOWNTO 0) := "0001000000";
CONSTANT shlBH : std_logic_vector (9 DOWNTO 0) := "0000100000";
CONSTANT shrBH : std_logic_vector (9 DOWNTO 0) := "0000010000";
CONSTANT AaddBH : std_logic_vector (9 DOWNTO 0) := "0000001000";
CONSTANT AsubBH : std_logic_vector (9 DOWNTO 0) := "0000000100";
CONSTANT AmulBH : std_logic_vector (9 DOWNTO 0) := "0000000010";
CONSTANT AcmpBH : std_logic_vector (9 DOWNTO 0) := "0000000001";
SIGNAL aluoutSignal, product : std_logic_vector (15 DOWNTO 0);
BEGIN
PROCESS (A, B, B15to0, AandB, AorB, notB, shlB, shrB, AaddB, AsubB, AmulB, cin, aluoutSignal,
product, AcmpB)--signal, product are added
VARIABLE temp : std_logic_vector (9 DOWNTO 0);
VARIABLE sum : std_logic_vector (16 DOWNTO 0);
VARIABLE sub : std_logic_vector (16 DOWNTO 0);
BEGIN
zout <= '0';
cout <= '0';
aluoutSignal <= (OTHERS=>'0');
temp := (B15to0, AandB, AorB, notB, shlB, shrB, AaddB, AsubB, AmulB, AcmpB);
sum := A + B + (16 DOWNTO 1=> '0', 0=> cin) ;
sub := A - B - (16 DOWNTO 1=> '0', 0=> cin);
CASE temp IS
WHEN B15to0H => aluoutSignal <= B;
WHEN AandBH => aluoutSignal <= A and B;
WHEN AorBH => aluoutSignal <= A or B;
WHEN notBH => aluoutSignal <= not (B);
WHEN shlBH => aluoutSignal <= B (14 DOWNTO 0) & B (0);
WHEN shrBH => aluoutSignal <= B (15) & B (15 DOWNTO 1);
WHEN AaddBH => aluoutSignal <= sum (15 DOWNTO 0);cout <= sum (16);
WHEN AsubBH => aluoutSignal <= sub (15 DOWNTO 0);cout <= sub (16);
WHEN AmulBH => aluoutSignal <= product; --A (7 DOWNTO 0) * B (7 DOWNTO 0);
WHEN AcmpBH => aluoutSignal <= (OTHERS=>'1');
IF (A>B) THEN
cout <= '1';
ELSE
cout <= '0';
END IF;
IF (A=B) THEN
zout <= '1';
ELSE
zout <= '0';
END IF;
WHEN OTHERS => aluoutSignal <= (OTHERS=>'0');
END CASE;
IF (aluoutSignal = "0000000000000000") THEN
zout <= '1';
END IF;
END PROCESS;
l1 : mult PORT MAP (A (7 DOWNTO 0), B (7 DOWNTO 0), product);
aluout <= aluoutSignal;
END dataflow;
------------------------------------------------------
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.std_logic_unsigned.ALL;
ENTITY DataPath IS
PORT (
clk : IN std_logic;
Databus : inout std_logic_vector (15 DOWNTO 0);
Addressbus : OUT std_logic_vector (15 DOWNTO 0);
ResetPC, PCplusI, PCplus1, RplusI, Rplus0, Rs_on_AddressUnitRSide, Rd_on_AddressUnitRSide,
EnablePC,
B15to0, AandB, AorB, notB, shlB, shrB, AaddB, AsubB, AmulB, AcmpB, RFLwrite, RFHwrite,
WPreset,
WPadd, IRload, SRload, Address_on_Databus, ALU_on_Databus, IR_on_LOpndBus,
IR_on_HOpndBus,
RFright_on_OpndBus, Cset, Creset, Zset, Zreset, shadow : IN std_logic;
Instruction : OUT std_logic_vector (7 DOWNTO 0);
Cout, Zout, ShadowEn : OUT std_logic
);
END DataPath;
ARCHITECTURE dataflow OF DataPath IS
COMPONENT AU
PORT (
Rside : IN std_logic_vector (15 DOWNTO 0);
Iside : IN std_logic_vector (7 DOWNTO 0);
Address : OUT std_logic_vector (15 DOWNTO 0);
clk, ResetPC, PCplusI, PCplus1, RplusI, Rplus0, EnablePC : IN std_logic
);
END COMPONENT;
FOR ALL : AU USE ENTITY WORK.AddressingUnit (dataflow);
COMPONENT ALU
PORT (
A, B : IN std_logic_vector (15 DOWNTO 0);
B15to0, AandB, AorB, notB, shlB, shrB, AaddB, AsubB, AmulB, AcmpB : IN std_logic;
aluout : OUT std_logic_vector (15 DOWNTO 0);
cin : IN std_logic;
zout, cout : OUT std_logic
);
END COMPONENT;
FOR ALL : ALU USE ENTITY WORK.ArithmeticUnit (dataflow);
COMPONENT RF
PORT (
input : IN std_logic_vector (15 DOWNTO 0);
clk : IN std_logic;
base : IN std_logic_vector (5 DOWNTO 0);
Laddr, Raddr : IN std_logic_vector (1 DOWNTO 0);
RFLwrite, RFHwrite : IN std_logic;
Lout, Rout : OUT std_logic_vector (15 DOWNTO 0)
);
END COMPONENT;
FOR ALL : RF USE ENTITY WORK.RegisterFile (dataflow);
COMPONENT IR
PORT (
input : IN std_logic_vector (15 DOWNTO 0);
IRload, clk : IN std_logic;
output : OUT std_logic_vector (15 DOWNTO 0)
);
END COMPONENT;
FOR ALL : IR USE ENTITY WORK.InstrunctionRegister (dataflow);
COMPONENT SR
PORT (
Cin, Zin, SRload, clk, Cset, Creset, Zset, Zreset : IN std_logic;
Cout, Zout : OUT std_logic
);
END COMPONENT;
FOR ALL : sr USE ENTITY WORK.StatusRegister (dataflow);
COMPONENT WP
PORT (
input : IN std_logic_vector (5 DOWNTO 0);
clk, WPreset, WPadd : IN std_logic;
output : OUT std_logic_vector (5 DOWNTO 0)
);
END COMPONENT;
FOR ALL : wp USE ENTITY WORK.WindowPointer (dataflow);
SIGNAL Right, Left, OpndBus, ALUout, IRout, Address, AddressUnitRSideBus : std_logic_vector
(15 DOWNTO 0);
SIGNAL SRCin, SRZin, SRZout, SRCout : std_logic;
SIGNAL WPout : std_logic_vector (5 DOWNTO 0);
SIGNAL Laddr, Raddr : std_logic_vector (1 DOWNTO 0);
BEGIN
AddressingUnit : AU PORT MAP (
AddressUnitRSideBus, IRout (7 DOWNTO 0), Address, clk, ResetPC, PCplusI, PCplus1, RplusI,
Rplus0, EnablePC
);
ArithmeticUnit : ALU PORT MAP (
Left, OpndBus, B15to0, AandB, AorB, notB, shlB, shrB, AaddB, AsubB, AmulB, AcmpB,
ALUout, SRCout, SRZin, SRCin
);
RegisterFile : RF PORT MAP (
Databus, clk, WPout, Laddr, Raddr, RFLwrite, RFHwrite, Left, Right
);
InstrunctionRegister : IR PORT MAP (Databus, IRload, clk, IRout);
StatusRegister : SR PORT MAP (SRCin, SRZin, SRload, clk, Cset, Creset, Zset, Zreset, SRCout,
SRZout);
WindowPointer : WP PORT MAP (IRout (5 DOWNTO 0), clk, WPreset, WPadd, WPout);
AddressUnitRSideBus <=
Right WHEN Rs_on_AddressUnitRSide='1' ELSE Left WHEN Rd_on_AddressUnitRSide='1' ELSE
(OTHERS=>'Z');
Addressbus <= Address;
Databus <= Address WHEN Address_on_Databus = '1' ELSE ALUout WHEN ALU_on_Databus = '1'
ELSE (OTHERS=>'Z');
OpndBus (7 DOWNTO 0) <= IRout (7 DOWNTO 0) WHEN IR_on_LOpndBus = '1' ELSE
(OTHERS=>'Z');
OpndBus (15 DOWNTO 8) <= IRout (7 DOWNTO 0) WHEN IR_on_HOpndBus = '1' ELSE
(OTHERS=>'Z');
OpndBus <= Right WHEN RFright_on_OpndBus = '1' ELSE (OTHERS=>'Z');
Zout <= SRZout;
Cout <= SRCout;
Instruction <= IRout(15 DOWNTO 8) WHEN Shadow='0' ELSE IRout(7 DOWNTO 0);
ShadowEn <= '0' WHEN IRout (7 DOWNTO 0)="00001111" ELSE '1';
Laddr <= IRout (11 DOWNTO 10) WHEN Shadow='0' ELSE IRout (3 DOWNTO 2);
Raddr <= IRout (9 DOWNTO 8) WHEN Shadow='0' ELSE IRout (1 DOWNTO 0);
END dataflow;
---------------------------------------------------------
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.std_logic_unsigned.ALL;
ENTITY controller IS
PORT (ExternalReset, clk : IN std_logic;
ResetPC, PCplusI, PCplus1, RplusI, Rplus0, Rs_on_AddressUnitRSide, Rd_on_AddressUnitRSide,
EnablePC, B15to0, AandB, AorB, notB, shlB, shrB, AaddB, AsubB, AmulB, AcmpB, RFLwrite,
RFHwrite, WPreset, WPadd, IRload, SRload, Address_on_Databus, ALU_on_Databus,
IR_on_LOpndBus,
IR_on_HOpndBus, RFright_on_OpndBus, ReadMem, WriteMem, ReadIO, WriteIO,
Cset, Creset, Zset, Zreset, Shadow : OUT std_logic;
Instruction : IN std_logic_vector (7 DOWNTO 0);
Cflag, Zflag, memDataReady, ShadowEn : IN std_logic
);
END controller;
ARCHITECTURE dataflow OF controller IS
TYPE state IS (reset, halt, fetch, memread, exec1, exec2, exec1lda, exec1sta, exec2lda, exec2sta,
incpc);
CONSTANT b0000 : std_logic_vector (3 DOWNTO 0) := "0000";
CONSTANT b1111 : std_logic_vector (3 DOWNTO 0) := "1111";
CONSTANT nop : std_logic_vector (3 DOWNTO 0) := "0000";
CONSTANT hlt : std_logic_vector (3 DOWNTO 0) := "0001";
CONSTANT szf : std_logic_vector (3 DOWNTO 0) := "0010";
CONSTANT czf : std_logic_vector (3 DOWNTO 0) := "0011";
CONSTANT scf : std_logic_vector (3 DOWNTO 0) := "0100";
CONSTANT ccf : std_logic_vector (3 DOWNTO 0) := "0101";
CONSTANT cwp : std_logic_vector (3 DOWNTO 0) := "0110";
CONSTANT jpr : std_logic_vector (3 DOWNTO 0) := "0111";
CONSTANT brz : std_logic_vector (3 DOWNTO 0) := "1000";
CONSTANT brc : std_logic_vector (3 DOWNTO 0) := "1001";
CONSTANT awp : std_logic_vector (3 DOWNTO 0) := "1010";
CONSTANT mvr : std_logic_vector (3 DOWNTO 0) := "0001";
CONSTANT lda : std_logic_vector (3 DOWNTO 0) := "0010";
CONSTANT sta : std_logic_vector (3 DOWNTO 0) := "0011";
CONSTANT inp : std_logic_vector (3 DOWNTO 0) := "0100";
CONSTANT oup : std_logic_vector (3 DOWNTO 0) := "0101";
CONSTANT anl : std_logic_vector (3 DOWNTO 0) := "0110";
CONSTANT orr : std_logic_vector (3 DOWNTO 0) := "0111";
CONSTANT nol : std_logic_vector (3 DOWNTO 0) := "1000";
CONSTANT shl : std_logic_vector (3 DOWNTO 0) := "1001";
CONSTANT shr : std_logic_vector (3 DOWNTO 0) := "1010";
CONSTANT add : std_logic_vector (3 DOWNTO 0) := "1011";
CONSTANT sub : std_logic_vector (3 DOWNTO 0) := "1100";
CONSTANT mul : std_logic_vector (3 DOWNTO 0) := "1101";
CONSTANT cmp : std_logic_vector (3 DOWNTO 0) := "1110";
CONSTANT mil : std_logic_vector (1 DOWNTO 0) := "00";
CONSTANT mih : std_logic_vector (1 DOWNTO 0) := "01";
CONSTANT spc : std_logic_vector (1 DOWNTO 0) := "10";
CONSTANT jpa : std_logic_vector (1 DOWNTO 0) := "11";
SIGNAL Pstate, Nstate : state;
SIGNAL Regd_MemDataReady: std_logic;
BEGIN
PROCESS (Instruction, Pstate, ExternalReset, Cflag, Zflag, Regd_MemDataReady, ShadowEn)
BEGIN
ResetPC <= '0'; PCplusI <= '0'; PCplus1 <= '0'; RplusI <= '0'; Rplus0 <= '0'; EnablePC <= '0';
B15to0 <= '0'; AandB <= '0'; AorB <= '0'; notB <= '0';shrB <= '0';shlB <= '0'; AaddB <= '0';
AsubB <= '0'; AmulB <= '0';AcmpB <= '0'; RFLwrite <= '0';RFHwrite <= '0'; WPreset <= '0';
WPadd <= '0';IRload <= '0'; SRload <= '0'; Address_on_Databus <= '0'; ALU_on_Databus <= '0';
IR_on_LOpndBus <= '0';IR_on_HOpndBus <= '0'; RFright_on_OpndBus <= '0'; ReadMem <= '0';
WriteMem <= '0'; ReadIO <= '0'; WriteIO <= '0'; Shadow <= '0'; Cset <= '0'; Creset <= '0';
Zset <= '0'; Zreset <= '0'; Rs_on_AddressUnitRSide <= '0'; Rd_on_AddressUnitRSide <= '0';
CASE Pstate IS
WHEN reset =>
IF (ExternalReset = '1') THEN
WPreset <= '1';
ResetPC <= '1';
EnablePC <= '1';
Creset <= '1';
Zreset <= '1';
Nstate <= reset;
ELSE
Nstate <= fetch;
END IF;
WHEN halt =>
IF (ExternalReset = '1') THEN
Nstate <= fetch;
ELSE
Nstate <= halt;
END IF;
WHEN fetch =>
IF (ExternalReset = '1') THEN
Nstate <= reset;
ELSE
ReadMem <= '1';
Nstate <= memread;
END IF;
WHEN memread =>
IF (ExternalReset = '1') THEN
Nstate <= reset;
ELSE
IF (Regd_MemDataReady = '0') THEN
ReadMem <= '1';
Nstate <= memread;
ELSE
ReadMem <= '1';
IRload <= '1';
Nstate <= exec1;
END IF;
END IF;
WHEN exec1 =>
IF (ExternalReset = '1') THEN
Nstate <= reset;
ELSE
CASE Instruction (7 DOWNTO 4)is
WHEN b0000 =>
CASE Instruction (3 DOWNTO 0) IS
WHEN nop =>
IF (ShadowEn='1') THEN
Nstate <= exec2;
ELSE
PCplus1 <= '1';
EnablePC <= '1';
Nstate <= fetch;
END IF;
WHEN hlt =>
Nstate <= halt;
WHEN szf =>
zset <= '1';
IF (ShadowEn='1') THEN
Nstate <= exec2;
ELSE
PCplus1 <= '1';
EnablePC <= '1';
Nstate <= fetch;
END IF;
WHEN czf =>
zreset <= '1';
IF (ShadowEn='1') THEN
Nstate <= exec2;
ELSE
PCplus1 <= '1';
EnablePC <= '1';
Nstate <= fetch;
END IF;
WHEN scf =>
cset <= '1';
IF (ShadowEn='1') THEN
Nstate <= exec2;
ELSE
PCplus1 <= '1';
EnablePC <= '1';
Nstate <= fetch;
END IF;
WHEN ccf =>
creset <= '1';
IF (ShadowEn='1') THEN
Nstate <= exec2;
ELSE
PCplus1 <= '1';
EnablePC <= '1';
Nstate <= fetch;
END IF;
WHEN cwp =>
WPreset <= '1';
IF (ShadowEn='1') THEN
Nstate <= exec2;
ELSE
PCplus1 <= '1';
EnablePC <= '1';
Nstate <= fetch;
END IF;
WHEN jpr =>
PCplusI <= '1';
EnablePC <= '1';
Nstate <= fetch;
WHEN brz =>
IF (Zflag = '1') THEN
PCplusI <= '1';
EnablePC <= '1';
ELSE
PCplus1 <= '1';
EnablePC <= '1';
END IF;
Nstate <= fetch;
WHEN brc =>
IF (Cflag = '1') THEN
PCplusI <= '1';
EnablePC <= '1';
ELSE
PCplus1 <= '1';
EnablePC <= '1';
END IF;
Nstate <= fetch;
WHEN awp =>
PCplus1 <= '1';
EnablePC <= '1';
WPadd <= '1';
Nstate <= fetch;
WHEN OTHERS =>
PCplus1 <= '1';
EnablePC <= '1';
Nstate <= fetch;
END CASE;
WHEN mvr =>
RFright_on_OpndBus <= '1';
B15to0 <= '1';
ALU_on_Databus <= '1';
RFLwrite <= '1';
RFHwrite <= '1';
SRload <= '1';
IF (ShadowEn='1') THEN
Nstate <= exec2;
ELSE
PCplus1 <= '1';
EnablePC <= '1';
Nstate <= fetch;
END IF;
WHEN lda =>
Rplus0 <= '1';
Rs_on_AddressUnitRSide <= '1';
ReadMem <= '1';
RFLwrite <= '1';
RFHwrite <= '1';
Nstate <= exec1lda;
WHEN sta =>
Rplus0 <= '1';
Rd_on_AddressUnitRSide <= '1';
RFright_on_OpndBus <= '1';
B15to0 <= '1';
ALU_on_Databus <= '1';
WriteMem <= '1';
Nstate <= exec1sta;
WHEN inp =>
Rplus0 <= '1';
Rs_on_AddressUnitRSide <= '1';
ReadIO <= '1';
RFLwrite <= '1';
RFHwrite <= '1';
SRload <= '1';
IF (ShadowEn='1') THEN
Nstate <= exec2;
ELSE
Nstate <= incpc;
END IF;
WHEN oup =>
Rplus0 <= '1';
Rd_on_AddressUnitRSide <= '1';
B15to0 <= '1';
ALU_on_Databus <= '1';
WriteIO <= '1';
IF (ShadowEn='1') THEN
Nstate <= exec2;
ELSE
Nstate <= incpc;
END IF;
WHEN anl =>
RFright_on_OpndBus <= '1';
AandB <= '1';
ALU_on_Databus <= '1';
RFLwrite <= '1';
RFHwrite <= '1';
SRload <= '1';
IF (ShadowEn='1') THEN
Nstate <= exec2;
ELSE
Pcplus1 <= '1';
EnablePC <= '1';
Nstate <= fetch;
END IF;
WHEN orr =>
RFright_on_OpndBus <= '1';
AorB <= '1';
ALU_on_Databus <= '1';
RFLwrite <= '1';
RFHwrite <= '1';
SRload <= '1';
IF (ShadowEn='1') THEN
Nstate <= exec2;
ELSE
Pcplus1 <= '1';
EnablePC <= '1';
Nstate <= fetch;
END IF;
WHEN nol =>
RFright_on_OpndBus <= '1';
notB <= '1';
ALU_on_Databus <= '1';
RFLwrite <= '1';
RFHwrite <= '1';
SRload <= '1';
IF (ShadowEn='1') THEN
Nstate <= exec2;
ELSE
Pcplus1 <= '1';
EnablePC <= '1';
Nstate <= fetch;
END IF;
WHEN shl =>
RFright_on_OpndBus <= '1';
shlB <= '1';
ALU_on_Databus <= '1';
RFLwrite <= '1';
RFHwrite <= '1';
SRload <= '1';
IF (ShadowEn='1') THEN
Nstate <= exec2;
ELSE
Pcplus1 <= '1';
EnablePC <= '1';
Nstate <= fetch;
END IF;
WHEN shr =>
RFright_on_OpndBus <= '1';
shrB <= '1';
ALU_on_Databus <= '1';
RFLwrite <= '1';
RFHwrite <= '1';
SRload <= '1';
IF (ShadowEn='1') THEN
Nstate <= exec2;
ELSE
Pcplus1 <= '1';
EnablePC <= '1';
Nstate <= fetch;
END IF;
WHEN add =>
RFright_on_OpndBus <= '1';
AaddB <= '1';
ALU_on_Databus <= '1';
RFLwrite <= '1';
RFHwrite <= '1';
SRload <= '1';
IF (ShadowEn='1') THEN
Nstate <= exec2;
ELSE
Pcplus1 <= '1';
EnablePC <= '1';
Nstate <= fetch;
END IF;
WHEN sub =>
RFright_on_OpndBus <= '1';
AsubB <= '1';
ALU_on_Databus <= '1';
RFLwrite <= '1';
RFHwrite <= '1';
SRload <= '1';
IF (ShadowEn='1') THEN
Nstate <= exec2;
ELSE
Pcplus1 <= '1';
EnablePC <= '1';
Nstate <= fetch;
END IF;
WHEN mul =>
RFright_on_OpndBus <= '1';
AmulB <= '1';
ALU_on_Databus <= '1';
RFLwrite <= '1';
RFHwrite <= '1';
SRload <= '1';
IF (ShadowEn='1') THEN
Nstate <= exec2;
ELSE
Pcplus1 <= '1';
EnablePC <= '1';
Nstate <= fetch;
END IF;
WHEN cmp =>
RFright_on_OpndBus <= '1';
AcmpB <= '1';
SRload <= '1';
IF (ShadowEn='1') THEN
Nstate <= exec2;
ELSE
Pcplus1 <= '1';
EnablePC <= '1';
Nstate <= fetch;
END IF;
WHEN b1111 =>
CASE Instruction (1 DOWNTO 0) IS
WHEN mil =>
IR_on_LOpndBus <= '1';
ALU_on_Databus <= '1';
B15to0 <= '1';
RFLwrite <= '1';
SRload <= '1';
Pcplus1 <= '1';
EnablePC <= '1';
Nstate <= fetch;
WHEN mih =>
IR_on_HOpndBus <= '1';
ALU_on_Databus <= '1';
B15to0 <= '1';
RFHwrite <= '1';
SRload <= '1';
Pcplus1 <= '1';
EnablePC <= '1';
Nstate <= fetch;
WHEN spc =>
PCplusI <= '1';
Address_on_Databus <= '1';
RFLwrite <= '1';
RFHwrite <= '1';
EnablePC <= '1';
Nstate <= incpc;
WHEN jpa =>
Rd_on_AddressUnitRSide <= '1';
RplusI <= '1';
EnablePC <= '1';
Nstate <= fetch;
WHEN OTHERS =>
Nstate <= fetch;
END CASE;
WHEN OTHERS => Nstate <= fetch;
END CASE;
END IF;
WHEN exec1lda =>
IF (ExternalReset = '1') THEN
Nstate <= reset;
ELSE
IF (Regd_MemDataReady = '0') THEN
Rplus0 <= '1';
Rs_on_AddressUnitRSide <= '1';
ReadMem <= '1';
RFLwrite <= '1';
RFHwrite <= '1';
Nstate <= exec1lda;
ELSE
IF (ShadowEn='1') THEN
Nstate <= exec2;
ELSE
PCplus1 <= '1';
EnablePC <= '1';
Nstate <= fetch;
END IF;
END IF;
END IF;
WHEN exec1sta =>
IF (ExternalReset = '1') THEN
Nstate <= reset;
ELSE
IF (Regd_MemDataReady = '0') THEN
Rplus0 <= '1';
Rd_on_AddressUnitRSide <= '1';
RFright_on_OpndBus <= '1';
B15to0 <= '1';
ALU_on_Databus <= '1';
WriteMem <= '1';
Nstate <= exec1sta;
ELSE
-- WriteMem <= '1';
IF (ShadowEn='1') THEN
Nstate <= exec2;
ELSE
Nstate <= incpc;
END IF;
END IF;
END IF;
WHEN exec2 =>
shadow <= '1';
IF (ExternalReset = '1') THEN
Nstate <= reset;
ELSE
CASE Instruction (7 DOWNTO 4)is
WHEN b0000 =>
CASE Instruction (3 DOWNTO 0) IS
WHEN hlt =>
Nstate <= halt;
WHEN szf =>
zset <= '1';
PcPlus1 <= '1';
EnablePC <= '1';
Nstate <= fetch;
WHEN czf =>
zreset <= '1';
PcPlus1 <= '1';
EnablePC <= '1';
Nstate <= fetch;
WHEN scf =>
cset <= '1';
PcPlus1 <= '1';
EnablePC <= '1';
Nstate <= fetch;
WHEN ccf =>
creset <= '1';
PcPlus1 <= '1';
EnablePC <= '1';
Nstate <= fetch;
WHEN cwp =>
WPreset <= '1';
PcPlus1 <= '1';
EnablePC <= '1';
Nstate <= fetch;
WHEN OTHERS =>
PcPlus1 <= '1';
EnablePC <= '1';
Nstate <= fetch;
END CASE;
WHEN mvr =>
RFright_on_OpndBus <= '1';
B15to0 <= '1';
ALU_on_Databus <= '1';
RFLwrite <= '1';
RFHwrite <= '1';
SRload <= '1';
PcPlus1 <= '1';
EnablePC <= '1';
Nstate <= fetch;
WHEN lda =>
Rplus0 <= '1';
Rs_on_AddressUnitRSide <= '1';
ReadMem <= '1';
RFLwrite <= '1';
RFHwrite <= '1';
Nstate <= exec2lda;
WHEN sta =>
Rplus0 <= '1';
Rd_on_AddressUnitRSide <= '1';
RFright_on_OpndBus <= '1';
B15to0 <= '1';
ALU_on_Databus <= '1';
WriteMem <= '1';
Nstate <= exec2sta;
WHEN inp =>
Rplus0 <= '1';
Rs_on_AddressUnitRSide <= '1';
ReadIO <= '1';
RFLwrite <= '1';
RFHwrite <= '1';
SRload <= '1';
Nstate <= incpc;
WHEN oup =>
Rplus0 <= '1';
Rd_on_AddressUnitRSide <= '1';
B15to0 <= '1';
ALU_on_Databus <= '1';
WriteIO <= '1';
Nstate <= incpc;
WHEN anl =>
RFright_on_OpndBus <= '1';
AandB <= '1';
ALU_on_Databus <= '1';
RFLwrite <= '1';
RFHwrite <= '1';
SRload <= '1';
PcPlus1 <= '1';
EnablePC <= '1';
Nstate <= fetch;
WHEN orr =>
RFright_on_OpndBus <= '1';
AorB <= '1';
ALU_on_Databus <= '1';
RFLwrite <= '1';
RFHwrite <= '1';
SRload <= '1';
PcPlus1 <= '1';
EnablePC <= '1';
Nstate <= fetch;
WHEN nol =>
RFright_on_OpndBus <= '1';
notB <= '1';
ALU_on_Databus <= '1';
RFLwrite <= '1';
RFHwrite <= '1';
SRload <= '1';
PcPlus1 <= '1';
EnablePC <= '1';
Nstate <= fetch;
WHEN shl =>
RFright_on_OpndBus <= '1';
shlB <= '1';
ALU_on_Databus <= '1';
RFLwrite <= '1';
RFHwrite <= '1';
SRload <= '1';
PcPlus1 <= '1';
EnablePC <= '1';
Nstate <= fetch;
WHEN shr =>
RFright_on_OpndBus <= '1';
shrB <= '1';
ALU_on_Databus <= '1';
RFLwrite <= '1';
RFHwrite <= '1';
SRload <= '1';
PcPlus1 <= '1';
EnablePC <= '1';
Nstate <= fetch;
WHEN add =>
RFright_on_OpndBus <= '1';
AaddB <= '1';
ALU_on_Databus <= '1';
RFLwrite <= '1';
RFHwrite <= '1';
SRload <= '1';
PcPlus1 <= '1';
EnablePC <= '1';
Nstate <= fetch;
WHEN sub =>
RFright_on_OpndBus <= '1';
AsubB <= '1';
ALU_on_Databus <= '1';
RFLwrite <= '1';
RFHwrite <= '1';
SRload <= '1';
PcPlus1 <= '1';
EnablePC <= '1';
Nstate <= fetch;
WHEN mul =>
RFright_on_OpndBus <= '1';
AmulB <= '1';
ALU_on_Databus <= '1';
RFLwrite <= '1';
RFHwrite <= '1';
SRload <= '1';
PcPlus1 <= '1';
EnablePC <= '1';
Nstate <= fetch;
WHEN cmp =>
RFright_on_OpndBus <= '1';
AcmpB <= '1';
SRload <= '1';
PcPlus1 <= '1';
EnablePC <= '1';
Nstate <= fetch;
WHEN OTHERS => Nstate <= fetch;
END CASE;
END IF;
WHEN exec2lda =>
shadow <= '1';
IF (ExternalReset = '1') THEN
Nstate <= reset;
ELSE
IF (Regd_MemDataReady = '0') THEN
Rplus0 <= '1';
Rs_on_AddressUnitRSide <= '1';
ReadMem <= '1';
RFLwrite <= '1';
RFHwrite <= '1';
Nstate <= exec2lda;
ELSE
PcPlus1 <= '1';
EnablePC <= '1';
Nstate <= fetch;
END IF;
END IF;
WHEN exec2sta =>
shadow <= '1';
IF (ExternalReset = '1') THEN
Nstate <= reset;
ELSE
IF (Regd_MemDataReady = '0') THEN
Rplus0 <= '1';
Rd_on_AddressUnitRSide <= '1';
RFright_on_OpndBus <= '1';
B15to0 <= '1';
ALU_on_Databus <= '1';
WriteMem <= '1';
Nstate <= exec2sta;
ELSE
Nstate <= incpc;
END IF;
END IF;
WHEN incpc =>
PcPlus1 <= '1';
EnablePC <= '1';
Nstate <= fetch;
WHEN OTHERS => Nstate <= reset;
END CASE;
END PROCESS;
PROCESS (clk)
BEGIN
IF (clk = '1') THEN
Regd_MemDataReady <= memDataReady;
Pstate <= Nstate;
END IF;
END PROCESS;
END dataflow;
-------------------------------------------
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.std_logic_unsigned.ALL;
ENTITY Sayeh IS
PORT (
clk : IN std_logic;
ReadMem, WriteMem, ReadIO, WriteIO : OUT std_logic;
Databus : inout std_logic_vector (15 DOWNTO 0);
Addressbus : OUT std_logic_vector (15 DOWNTO 0);
ExternalReset, memdataready : IN std_logic
);
END Sayeh;
ARCHITECTURE dataflow OF Sayeh IS
COMPONENT dp
PORT (
clk : IN std_logic;
Databus : inout std_logic_vector (15 DOWNTO 0);
Addressbus : OUT std_logic_vector (15 DOWNTO 0);
ResetPC, PCplusI, PCplus1, RplusI, Rplus0, Rs_on_AddressUnitRSide,
Rd_on_AddressUnitRSide,
EnablePC, B15to0, AandB, AorB, notB, shlB, shrB, AaddB, AsubB, AmulB, AcmpB, RFLwrite,
RFHwrite,
WPreset, WPadd, IRload, SRload, Address_on_Databus, ALU_on_Databus, IR_on_LOpndBus,
IR_on_HOpndBus, RFright_on_OpndBus, Cset, Creset, Zset, Zreset, shadow : IN std_logic;
Instruction : OUT std_logic_vector (7 DOWNTO 0);
Cout, Zout, ShadowEn : OUT std_logic
);
END COMPONENT;
FOR ALL : dp USE ENTITY WORK.DataPath (dataflow);
COMPONENT ctrl
PORT (
ExternalReset, clk : IN std_logic;
ResetPC, PCplusI, PCplus1, RplusI, Rplus0, Rs_on_AddressUnitRSide,
Rd_on_AddressUnitRSide, EnablePC,
B15to0, AandB, AorB, notB, shlB, shrB, AaddB, AsubB, AmulB, AcmpB, RFLwrite, RFHwrite,
WPreset,
WPadd, IRload, SRload, Address_on_Databus, ALU_on_Databus, IR_on_LOpndBus,
IR_on_HOpndBus,
RFright_on_OpndBus, ReadMem, WriteMem, ReadIO, WriteIO, Cset,
Creset, Zset, Zreset, shadow : OUT std_logic;
Instruction : IN std_logic_vector (7 DOWNTO 0);
Cflag, Zflag, memdataready, ShadowEn : IN std_logic
);
END COMPONENT;
FOR ALL : ctrl USE ENTITY WORK.Controller (dataflow);
SIGNAL Instruction : std_logic_vector (7 DOWNTO 0);
signal
ResetPC, PCplusI, PCplus1, RplusI, Rplus0, Rs_on_AddressUnitRSide, Rd_on_AddressUnitRSide,
EnablePC, B15to0, Bleast, AandB, AorB, notB, shlB, shrB, AaddB, AsubB, AmulB, AcmpB,
RFLwrite, RFHwrite, RFzeroLeft, RFzeroRight, WPreset, WPadd, IRload, SRload,
Address_on_Databus, ALU_on_Databus, IR_on_LOpndBus, IR_on_HOpndBus,
RFright_on_OpndBus,
Cset, Creset, Zset, Zreset, shadow, Cflag, Zflag, ShadowEn : std_logic;
BEGIN
datapath : dp PORT MAP (
clk, Databus, Addressbus, ResetPC, PCplusI, PCplus1, RplusI, Rplus0,
Rs_on_AddressUnitRSide, Rd_on_AddressUnitRSide, EnablePC, B15to0, AandB,
AorB, notB, shlB, shrB, AaddB, AsubB, AmulB, AcmpB, RFLwrite, RFHwrite,
WPreset, WPadd, IRload, SRload, Address_on_Databus, ALU_on_Databus,
IR_on_LOpndBus, IR_on_HOpndBus, RFright_on_OpndBus, Cset, Creset, Zset,
Zreset, shadow, Instruction, Cflag, Zflag, ShadowEn
);
controller : ctrl PORT MAP (
ExternalReset, clk, ResetPC, PCplusI, PCplus1, RplusI, Rplus0,
Rs_on_AddressUnitRSide,Rd_on_AddressUnitRSide, EnablePC, B15to0,
AandB, AorB, notB, shlB, shrB, AaddB, AsubB, AmulB, AcmpB, RFLwrite,
RFHwrite, WPreset, WPadd, IRload, SRload, Address_on_Databus,
ALU_on_Databus, IR_on_LOpndBus, IR_on_HOpndBus, RFright_on_OpndBus,
ReadMem, WriteMem, ReadIO, WriteIO, Cset, Creset, Zset, Zreset, shadow,
Instruction, Cflag, Zflag, memdataready, ShadowEn
);
END dataflow;
------------------------------------------
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.std_logic_unsigned.ALL;
USE IEEE.std_logic_arith.ALL;
USE std.textio.ALL;
USE IEEE.std_logic_textio.ALL;
ENTITY Sayehmemory IS
GENERIC (blocksize : integer := 1024; segmentsno : integer := 64);
PORT (
clk : IN STD_LOGIC;
readmem : IN STD_LOGIC;
writemem : IN STD_LOGIC;
addressbus : IN STD_LOGIC_VECTOR (15 DOWNTO 0);
databus : INOUT STD_LOGIC_VECTOR (15 DOWNTO 0);
memdataready : OUT std_logic
);
END Sayehmemory;
ARCHITECTURE behavioral OF Sayehmemory IS
CONSTANT shadowins : std_logic_vector (7 DOWNTO 0) := "00001111";
TYPE mem_TYPE IS ARRAY (0 TO blocksize-1) OF STD_LOGIC_VECTOR (15 DOWNTO 0); --Data
TYPE for a seqment OF memory
--Assembler convert and amp asm FILE TO memory
PROCEDURE assembler (VARIABLE mem : OUT mem_type) IS
FILE code : text open read_mode IS "prog.txt";
VARIABLE instr : line;
VARIABLE addr_std_v : std_logic_vector(15 DOWNTO 0);
VARIABLE memonic : string (4 DOWNTO 1);
VARIABLE im_ch : character;
VARIABLE immediate : std_logic_vector (7 DOWNTO 0);
VARIABLE window_ptr : std_logic_vector (3 DOWNTO 0);
VARIABLE dest_reg, src_reg : std_logic_vector (3 DOWNTO 0);
VARIABLE immi_str2 : string (2 DOWNTO 1);
VARIABLE adr, addr : integer := -1;
VARIABLE shadowEn : boolean := false;
BEGIN
WHILE not ENDFILE (code) LOOP
readline (code, instr);
HREAD (instr, addr_std_v);
addr := conv_integer (addr_std_v);
addr := addr mod blocksize;
READ (instr, memonic);
CASE memonic IS
WHEN " nop" =>
IF (shadowEn=true) THEN
mem (adr) (7 DOWNTO 0) := (OTHERS=>'0');
ELSE
adr := adr+1;
mem (adr) (15 DOWNTO 8) := (OTHERS=>'0');
mem (adr) (7 DOWNTO 0) := shadowins;
END IF;
shadowEn := not shadowEn;
WHEN " hlt" =>
IF (shadowEn=true) THEN
mem (adr) (7 DOWNTO 0) := "00000001";
ELSE
adr := adr+1;
mem (adr) (15 DOWNTO 8) := "00000001";
mem (adr) (7 DOWNTO 0) := shadowins;
END IF;
shadowEn := not shadowEn;
WHEN " szf" =>
IF (shadowEn=true) THEN
mem (adr) (7 DOWNTO 0) := "00000010";
ELSE
adr := adr+1;
mem (adr) (15 DOWNTO 8) := "00000010";
mem (adr) (7 DOWNTO 0) := shadowins;
END IF;
shadowEn := not shadowEn;
WHEN " czf" =>
IF (shadowEn=true) THEN
mem (adr) (7 DOWNTO 0) := "00000011";
ELSE
adr := adr+1;
mem (adr) (15 DOWNTO 8) := "00000011";
mem (adr) (7 DOWNTO 0) := shadowins;
END IF;
shadowEn := not shadowEn;
WHEN " scf" =>
IF (shadowEn=true) THEN
mem (adr) (7 DOWNTO 0) := "00000100";
ELSE
adr := adr+1;
mem (adr) (15 DOWNTO 8) := "00000100";
mem (adr) (7 DOWNTO 0) := shadowins;
END IF;
shadowEn := not shadowEn;
WHEN " ccf" =>
IF (shadowEn=true) THEN
mem (adr) (7 DOWNTO 0) := "00000101";
ELSE
adr := adr+1;
mem (adr) (15 DOWNTO 8) := "00000101";
mem (adr) (7 DOWNTO 0) := shadowins;
END IF;
shadowEn := not shadowEn;
WHEN " cwp" =>
IF (shadowEn=true) THEN
mem (adr) (7 DOWNTO 0) := "00000110";
ELSE
adr := adr+1;
mem (adr) (15 DOWNTO 8) := "00000110";
mem (adr) (7 DOWNTO 0) := shadowins;
END IF;
shadowEn := not shadowEn;
WHEN " jpr" =>
shadowEn := false;
adr := adr+1;
mem (adr) (15 DOWNTO 8) := "00000111";
READ (instr, im_ch);
HREAD (instr, immediate);
mem (adr) (7 DOWNTO 0) := immediate;
WHEN " brz" =>
shadowEn := false;
adr := adr+1;
mem (adr) (15 DOWNTO 8) := "00001000";
READ (instr, im_ch);
HREAD (instr, immediate);
mem (adr) (7 DOWNTO 0) := immediate;
WHEN " brc" =>
shadowEn := false;
adr := adr+1;
mem (adr) (15 DOWNTO 8) := "00001001";
READ (instr, im_ch);
HREAD (instr, immediate);
mem (adr) (7 DOWNTO 0) := immediate;
WHEN " awp" =>
shadowEn := false;
adr := adr+1;
mem (adr) (15 DOWNTO 8) := "00001010";
mem (adr) (7 DOWNTO 3) := (OTHERS=>'0');
READ (instr, im_ch);
HREAD(instr, window_ptr);
mem (adr) (2 DOWNTO 0) := window_ptr (2 DOWNTO 0);
WHEN " mvr" =>
IF (shadowEn=true) THEN
mem (adr) (7 DOWNTO 4) := "0001";
READ (instr, immi_str2);
HREAD (instr, dest_reg);
mem (adr) (3 DOWNTO 2) := dest_reg (1 DOWNTO 0);
READ (instr, immi_str2);
HREAD (instr, src_reg);
mem (adr) (1 DOWNTO 0) := src_reg (1 DOWNTO 0);
ELSE
adr := adr+1;
mem (adr) (15 DOWNTO 12) := "0001";
READ (instr, immi_str2);
HREAD (instr, dest_reg);
mem (adr) (11 DOWNTO 10) := dest_reg (1 DOWNTO 0);
READ (instr, immi_str2);
HREAD (instr, src_reg);
mem (adr) (9 DOWNTO 8) := src_reg (1 DOWNTO 0);
mem (adr) (7 DOWNTO 0) := shadowins;
END IF;
shadowEn := not shadowEn;
WHEN " lda" =>
IF (shadowEn=true) THEN
mem (adr) (7 DOWNTO 4) := "0010";
READ (instr, immi_str2);
HREAD (instr, dest_reg);
mem (adr) (3 DOWNTO 2) := dest_reg (1 DOWNTO 0);
READ (instr, immi_str2);
HREAD (instr, src_reg);
mem (adr) (1 DOWNTO 0) := src_reg (1 DOWNTO 0);
ELSE
adr := adr+1;
mem (adr) (15 DOWNTO 12) := "0010";
READ (instr, immi_str2);
HREAD (instr, dest_reg);
mem (adr) (11 DOWNTO 10) := dest_reg (1 DOWNTO 0);
READ (instr, immi_str2);
HREAD (instr, src_reg);
mem (adr) (9 DOWNTO 8) := src_reg (1 DOWNTO 0);
mem (adr) (7 DOWNTO 0) := shadowins;
END IF;
shadowEn := not shadowEn;
WHEN " sta" =>
IF (shadowEn=true) THEN
mem (adr) (7 DOWNTO 4) := "0011";
READ (instr, immi_str2);
HREAD (instr, dest_reg);
mem (adr) (3 DOWNTO 2) := dest_reg (1 DOWNTO 0);
READ (instr, immi_str2);
HREAD (instr, src_reg);
mem (adr) (1 DOWNTO 0) := src_reg (1 DOWNTO 0);
ELSE
adr := adr+1;
mem (adr) (15 DOWNTO 12) := "0011";
READ (instr, immi_str2);
HREAD (instr, dest_reg);
mem (adr) (11 DOWNTO 10) := dest_reg (1 DOWNTO 0);
READ (instr, immi_str2);
HREAD (instr, src_reg);
mem (adr) (9 DOWNTO 8) := src_reg (1 DOWNTO 0);
mem (adr) (7 DOWNTO 0) := shadowins;
END IF;
shadowEn := not shadowEn;
WHEN " inp" =>
IF (shadowEn=true) THEN
mem (adr) (7 DOWNTO 4) := "0100";
READ (instr, immi_str2);
HREAD (instr, dest_reg);
mem (adr) (3 DOWNTO 2) := dest_reg (1 DOWNTO 0);
READ (instr, immi_str2);
HREAD (instr, src_reg);
mem (adr) (1 DOWNTO 0) := src_reg (1 DOWNTO 0);
ELSE
adr := adr+1;
mem (adr) (15 DOWNTO 12) := "0100";
READ (instr, immi_str2);
HREAD (instr, dest_reg);
mem (adr) (11 DOWNTO 10) := dest_reg (1 DOWNTO 0);
READ (instr, immi_str2);
HREAD (instr, src_reg);
mem (adr) (9 DOWNTO 8) := src_reg (1 DOWNTO 0);
mem (adr) (7 DOWNTO 0) := shadowins;
END IF;
shadowEn := not shadowEn;
WHEN " oup" =>
IF (shadowEn=true) THEN
mem (adr) (7 DOWNTO 4) := "0101";
READ (instr, immi_str2);
HREAD (instr, dest_reg);
mem (adr) (3 DOWNTO 2) := dest_reg (1 DOWNTO 0);
READ (instr, immi_str2);
HREAD (instr, src_reg);
mem (adr) (1 DOWNTO 0) := src_reg (1 DOWNTO 0);
ELSE
adr := adr+1;
mem (adr) (15 DOWNTO 12) := "0101";
READ (instr, immi_str2);
HREAD (instr, dest_reg);
mem (adr) (11 DOWNTO 10) := dest_reg (1 DOWNTO 0);
READ (instr, immi_str2);
HREAD (instr, src_reg);
mem (adr) (9 DOWNTO 8) := src_reg (1 DOWNTO 0);
mem (adr) (7 DOWNTO 0) := shadowins;
END IF;
shadowEn := not shadowEn;
WHEN " and" =>
IF (shadowEn=true) THEN
mem (adr) (7 DOWNTO 4) := "0110";
READ (instr, immi_str2);
HREAD (instr, dest_reg);
mem (adr) (3 DOWNTO 2) := dest_reg (1 DOWNTO 0);
READ (instr, immi_str2);
HREAD (instr, src_reg);
mem (adr) (1 DOWNTO 0) := src_reg (1 DOWNTO 0);
ELSE
adr := adr+1;
mem (adr) (15 DOWNTO 12) := "0110";
READ (instr, immi_str2);
HREAD (instr, dest_reg);
mem (adr) (11 DOWNTO 10) := dest_reg (1 DOWNTO 0);
READ (instr, immi_str2);
HREAD (instr, src_reg);
mem (adr) (9 DOWNTO 8) := src_reg (1 DOWNTO 0);
mem (adr) (7 DOWNTO 0) := shadowins;
END IF;
shadowEn := not shadowEn;
WHEN " orr" =>
IF (shadowEn=true) THEN
mem (adr) (7 DOWNTO 4) := "0111";
READ (instr, immi_str2);
HREAD (instr, dest_reg);
mem (adr) (3 DOWNTO 2) := dest_reg (1 DOWNTO 0);
READ (instr, immi_str2);
HREAD (instr, src_reg);
mem (adr) (1 DOWNTO 0) := src_reg (1 DOWNTO 0);
ELSE
adr := adr+1;
mem (adr) (15 DOWNTO 12) := "0111";
READ (instr, immi_str2);
HREAD (instr, dest_reg);
mem (adr) (11 DOWNTO 10) := dest_reg (1 DOWNTO 0);
READ (instr, immi_str2);
HREAD (instr, src_reg);
mem (adr) (9 DOWNTO 8) := src_reg (1 DOWNTO 0);
mem (adr) (7 DOWNTO 0) := shadowins;
END IF;
shadowEn := not shadowEn;
WHEN " not" =>
IF (shadowEn=true) THEN
mem (adr) (7 DOWNTO 4) := "1000";
READ (instr, immi_str2);
HREAD (instr, dest_reg);
mem (adr) (3 DOWNTO 2) := dest_reg (1 DOWNTO 0);
READ (instr, immi_str2);
HREAD (instr, src_reg);
mem (adr) (1 DOWNTO 0) := src_reg (1 DOWNTO 0);
ELSE
adr := adr+1;
mem (adr) (15 DOWNTO 12) := "1000";
READ (instr, immi_str2);
HREAD (instr, dest_reg);
mem (adr) (11 DOWNTO 10) := dest_reg (1 DOWNTO 0);
READ (instr, immi_str2);
HREAD (instr, src_reg);
mem (adr) (9 DOWNTO 8) := src_reg (1 DOWNTO 0);
mem (adr) (7 DOWNTO 0) := shadowins;
END IF;
shadowEn := not shadowEn;
WHEN " shl" =>
IF (shadowEn=true) THEN
mem (adr) (7 DOWNTO 4) := "1001";
READ (instr, immi_str2);
HREAD (instr, dest_reg);
mem (adr) (3 DOWNTO 2) := dest_reg (1 DOWNTO 0);
READ (instr, immi_str2);
HREAD (instr, src_reg);
mem (adr) (1 DOWNTO 0) := src_reg (1 DOWNTO 0);
ELSE
adr := adr+1;
mem (adr) (15 DOWNTO 12) := "1001";
READ (instr, immi_str2);
HREAD (instr, dest_reg);
mem (adr) (11 DOWNTO 10) := dest_reg (1 DOWNTO 0);
READ (instr, immi_str2);
HREAD (instr, src_reg);
mem (adr) (9 DOWNTO 8) := src_reg (1 DOWNTO 0);
mem (adr) (7 DOWNTO 0) := shadowins;
END IF;
shadowEn := not shadowEn;
WHEN " shr" =>
IF (shadowEn=true) THEN
mem (adr) (7 DOWNTO 4) := "1010";
READ (instr, immi_str2);
HREAD (instr, dest_reg);
mem (adr) (3 DOWNTO 2) := dest_reg (1 DOWNTO 0);
READ (instr, immi_str2);
HREAD (instr, src_reg);
mem (adr) (1 DOWNTO 0) := src_reg (1 DOWNTO 0);
ELSE
adr := adr+1;
mem (adr) (15 DOWNTO 12) := "1010";
READ (instr, immi_str2);
HREAD (instr, dest_reg);
mem (adr) (11 DOWNTO 10) := dest_reg (1 DOWNTO 0);
READ (instr, immi_str2);
HREAD (instr, src_reg);
mem (adr) (9 DOWNTO 8) := src_reg (1 DOWNTO 0);
mem (adr) (7 DOWNTO 0) := shadowins;
END IF;
shadowEn := not shadowEn;
WHEN " add" =>
IF (shadowEn=true) THEN
mem (adr) (7 DOWNTO 4) := "1011";
READ (instr, immi_str2);
HREAD (instr, dest_reg);
mem (adr) (3 DOWNTO 2) := dest_reg (1 DOWNTO 0);
READ (instr, immi_str2);
HREAD (instr, src_reg);
mem (adr) (1 DOWNTO 0) := src_reg (1 DOWNTO 0);
ELSE
adr := adr+1;
mem (adr) (15 DOWNTO 12) := "1011";
READ (instr, immi_str2);
HREAD (instr, dest_reg);
mem (adr) (11 DOWNTO 10) := dest_reg (1 DOWNTO 0);
READ (instr, immi_str2);
HREAD (instr, src_reg);
mem (adr) (9 DOWNTO 8) := src_reg (1 DOWNTO 0);
mem (adr) (7 DOWNTO 0) := shadowins;
END IF;
shadowEn := not shadowEn;
WHEN " sub" =>
IF (shadowEn=true) THEN
mem (adr) (7 DOWNTO 4) := "1100";
READ (instr, immi_str2);
HREAD (instr, dest_reg);
mem (adr) (3 DOWNTO 2) := dest_reg (1 DOWNTO 0);
READ (instr, immi_str2);
HREAD (instr, src_reg);
mem (adr) (1 DOWNTO 0) := src_reg (1 DOWNTO 0);
ELSE
adr := adr+1;
mem (adr) (15 DOWNTO 12) := "1100";
READ (instr, immi_str2);
HREAD (instr, dest_reg);
mem (adr) (11 DOWNTO 10) := dest_reg (1 DOWNTO 0);
READ (instr, immi_str2);
HREAD (instr, src_reg);
mem (adr) (9 DOWNTO 8) := src_reg (1 DOWNTO 0);
mem (adr) (7 DOWNTO 0) := shadowins;
END IF;
shadowEn := not shadowEn;
WHEN " mul" =>
IF (shadowEn=true) THEN
mem (adr) (7 DOWNTO 4) := "1101";
READ (instr, immi_str2);
HREAD (instr, dest_reg);
mem (adr) (3 DOWNTO 2) := dest_reg (1 DOWNTO 0);
READ (instr, immi_str2);
HREAD (instr, src_reg);
mem (adr) (1 DOWNTO 0) := src_reg (1 DOWNTO 0);
ELSE
adr := adr+1;
mem (adr) (15 DOWNTO 12) := "1101";
READ (instr, immi_str2);
HREAD (instr, dest_reg);
mem (adr) (11 DOWNTO 10) := dest_reg (1 DOWNTO 0);
READ (instr, immi_str2);
HREAD (instr, src_reg);
mem (adr) (9 DOWNTO 8) := src_reg (1 DOWNTO 0);
mem (adr) (7 DOWNTO 0) := shadowins;
END IF;
shadowEn := not shadowEn;
WHEN " cmp" =>
IF (shadowEn=true) THEN
mem (adr) (7 DOWNTO 4) := "1110";
READ (instr, immi_str2);
HREAD (instr, dest_reg);
mem (adr) (3 DOWNTO 2) := dest_reg (1 DOWNTO 0);
READ (instr, immi_str2);
HREAD (instr, src_reg);
mem (adr) (1 DOWNTO 0) := src_reg (1 DOWNTO 0);
ELSE
adr := adr+1;
mem (adr) (15 DOWNTO 12) := "1110";
READ (instr, immi_str2);
HREAD (instr, dest_reg);
mem (adr) (11 DOWNTO 10) := dest_reg (1 DOWNTO 0);
READ (instr, immi_str2);
HREAD (instr, src_reg);
mem (adr) (9 DOWNTO 8) := src_reg (1 DOWNTO 0);
mem (adr) (7 DOWNTO 0) := shadowins;
END IF;
shadowEn := not shadowEn;
WHEN " mil" =>
shadowEn := false;
adr := adr+1;
mem (adr) (15 DOWNTO 12) := "1111";
READ (instr, immi_str2);
HREAD (instr, dest_reg);
mem (adr) (11 DOWNTO 10) := dest_reg (1 DOWNTO 0);
mem (adr) (9 DOWNTO 8) := "00";
READ (instr, im_ch);
HREAD (instr, immediate);
mem (adr) (7 DOWNTO 0) := immediate;
WHEN " mih" =>
shadowEn := false;
adr := adr+1;
mem (adr) (15 DOWNTO 12) := "1111";
READ (instr, immi_str2);
HREAD (instr, dest_reg);
mem (adr) (11 DOWNTO 10) := dest_reg (1 downto 0);
mem (adr) (9 DOWNTO 8) := "01";
READ (instr, im_ch);
HREAD (instr, immediate);
mem (adr) (7 DOWNTO 0) := immediate;
WHEN " spc" =>
shadowEn := false;
adr := adr+1;
mem (adr) (15 DOWNTO 12) := "1111";
READ (instr, immi_str2);
HREAD (instr, dest_reg);
mem (adr) (11 DOWNTO 10) := dest_reg (1 DOWNTO 0);
mem (adr) (9 DOWNTO 8) := "10";
READ (instr, im_ch);
HREAD (instr, immediate);
mem (adr) (7 DOWNTO 0) := immediate;
WHEN " jpa" =>
shadowEn := false;
adr := adr+1;
mem (adr) (15 DOWNTO 12) := "1111";
READ (instr, immi_str2);
HREAD (instr, dest_reg);
mem (adr) (11 DOWNTO 10) := dest_reg (1 DOWNTO 0);
mem (adr) (9 DOWNTO 8) := "11";
READ (instr, im_ch);
HREAD (instr, immediate);
mem (adr) (7 DOWNTO 0) := immediate;
WHEN OTHERS =>
mem (adr) := (OTHERS=>'0');
END CASE;
END LOOP;
file_close (code);
END;
--Load a segment from a file
PROCEDURE memload (buffermem : OUT mem_type; fileno : IN integer) IS
VARIABLE hexcode : String (4 DOWNTO 1);
VARIABLE memline : line;
VARIABLE offset : integer := 0;
VARIABLE err_check : file_open_status;
VARIABLE hexcode_v : std_logic_vector (15 DOWNTO 0);
FILE f : text;
BEGIN
buffermem := (OTHERS => (OTHERS =>'0'));
file_open (err_check, f, ("mem" & integer'image (fileno) & ".hex"), read_mode);
IF err_check = open_ok THEN
WHILE not ENDFILE (f) LOOP
readline (f, memline);
HREAD (memline, hexcode_v);
buffermem (offset) := hexcode_v;
offset := offset+1;
END LOOP;
file_close (f);
END IF;
END memload;
--Write memory data OF a segment TO its corresponding file
PROCEDURE updateFILE (buffermem : IN mem_type; fileno : IN integer) IS
VARIABLE memline : line;
FILE f : text open write_mode IS ("mem" & integer'image (fileno) & ".hex");
BEGIN
for i in 0 TO blocksize-1 LOOP
HWRITE (memline, buffermem (i));
writeline (f, memline);
END LOOP;
file_close (f);
END updatefile;
BEGIN
PROCESS (readmem,writemem,clk) --(clk)
VARIABLE buffermem : mem_type := (OTHERS=> (OTHERS=>'0'));
VARIABLE ad : INTEGER;
VARIABLE memloadedno : integer := segmentsno+1;
VARIABLE changemem : BOOLEAN := false;
VARIABLE init : boolean := true;
BEGIN
IF (init = true) THEN
assembler (buffermem);
UpdateFILE (buffermem, 1);
memloadedno := 1;
init := false;
END IF;
ad := conv_integer (addressbus);
--IF (clk='0') THEN
IF (readmem = '0') THEN
memdataready <= '0';
databus <= (OTHERS=>'Z');
END IF;
--END IF;
IF (clk='0') THEN
IF (readmem = '1') THEN
memdataready <= '0';
IF (ad >= (segmentsno*blocksize)) THEN
databus <= (OTHERS => 'Z');
ELSE
IF (memloadedno /= ( (ad/blocksize)+1)) THEN
IF memloadedno/= (segmentsno+1) THEN
IF changemem=true THEN UpdateFILE (buffermem, memloadedno); END IF;
END IF;
memload (buffermem, ( (ad/blocksize)+1));
changemem := false;
memloadedno := (ad/blocksize)+1;
databus <= buffermem (ad mod blocksize);
ELSE
databus <= buffermem (ad mod blocksize);
END IF;
END IF;
memdataready <= '1';
ELSIF (writemem = '1') THEN
memdataready <= '0';
IF (ad < (segmentsno*blocksize)) THEN
IF (memloadedno = ( (ad/blocksize)+1)) THEN
IF buffermem (ad mod blocksize)/=databus THEN changemem := true; END IF;
buffermem (ad mod blocksize) := databus;
IF changemem=true THEN
UpdateFILE (buffermem, memloadedno);
changemem := false;
END IF;
ELSE
IF memloadedno/= (segmentsno+1) THEN
IF changemem=true THEN UpdateFILE (buffermem, memloadedno); END IF;
END IF;
memloadedno := (ad/blocksize)+1;
memload (buffermem, memloadedno);
changemem := false;
IF buffermem (ad mod blocksize)/=databus THEN changemem := true; END IF;
buffermem (ad mod blocksize) := databus;
IF changemem=true THEN
UpdateFILE (buffermem, memloadedno);
changemem := false;
END IF;
END IF;
END IF;
memdataready <= '1';
END IF;
END IF;
END PROCESS;
END behavioral;
----------------------------
--Sayeh testbench
----------------------------
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.std_logic_unsigned.ALL;
ENTITY TestSayeh IS
END TestSayeh;
ARCHITECTURE dataflow OF TestSayeh IS
COMPONENT cpu
PORT (
clk : IN std_logic;
ReadMem, WriteMem, ReadIO, WriteIO : OUT std_logic;
Databus : inout std_logic_vector (15 DOWNTO 0);
Addressbus : OUT std_logic_vector (15 DOWNTO 0);
ExternalReset, memdataready : IN std_logic
);
END COMPONENT;
FOR ALL : cpu USE ENTITY WORK.Sayeh (dataflow);
COMPONENT mem
PORT (
clk : IN std_logic;
ReadMem, WriteMem : IN std_logic;
Addressbus : IN std_logic_vector (15 DOWNTO 0);
DataBus : inout std_logic_vector (15 DOWNTO 0);
memdataready : OUT std_logic
);
END COMPONENT;
FOR ALL : mem USE ENTITY WORK.SayehMemory (behavioral);
SIGNAL clk : std_logic := '0';
SIGNAL ReadMem, WriteMem, ReadIO, WriteIO, ExternalReset, memdataready : std_logic;
SIGNAL Databus, Addressbus : std_logic_vector (15 DOWNTO 0);
BEGIN
clk <= not (clk) after 5 ns WHEN now<1000000 ns ELSE clk;
ExternalReset <= '1', '0' after 27 ns;
processor : cpu PORT MAP (clk, ReadMem, WriteMem, ReadIO, WriteIO,
Databus, Addressbus, ExternalReset, memdataready);
memory : mem PORT MAP (clk, ReadMem, WriteMem, Addressbus, DataBus, memdataready);
END dataflow;
Prueba con este programa prog.txt
0000 mil r0 00 r0=1024 starting address in memory 0001 mih r0 04 0002 mil r1 10 r0=1024 starting address in memory 0003 mih r1 00 0004 sta r1 r0 (r4)=r6 0005 mil r2 00 r0=1024 starting address in memory 0006 mih r2 03 0007 mil r3 11 r0=1024 starting address in memory 0008 mih r3 00 0009 sta r3 r2 (r4)=r6