Line 81... |
Line 81... |
process (currentCpuState)
|
process (currentCpuState)
|
variable cyclesExecute : integer range 0 to 20; -- Cycles to wait while executing instruction
|
variable cyclesExecute : integer range 0 to 20; -- Cycles to wait while executing instruction
|
variable opcodeIR : std_logic_vector(5 downto 0);
|
variable opcodeIR : std_logic_vector(5 downto 0);
|
variable operand_reg1 : std_logic_vector(3 downto 0);
|
variable operand_reg1 : std_logic_vector(3 downto 0);
|
variable operand_imm : std_logic_vector(21 downto 0);
|
variable operand_imm : std_logic_vector(21 downto 0);
|
|
variable accDp : std_logic_vector(n downto 0); -- Value stored from DataPath
|
begin
|
begin
|
opcodeIR := IR((IR'HIGH) downto (IR'HIGH - 5));
|
opcodeIR := IR((IR'HIGH) downto (IR'HIGH - 5));
|
operand_reg1 := IR((IR'HIGH - 6) downto (IR'HIGH - 9)); -- 4 bits register operand1 (Max 16 registers)
|
operand_reg1 := IR((IR'HIGH - 6) downto (IR'HIGH - 9)); -- 4 bits register operand1 (Max 16 registers)
|
operand_imm := IR((IR'HIGH - 10) downto (IR'LOW)); -- 22 bits imediate value (Max value 4194304)
|
operand_imm := IR((IR'HIGH - 10) downto (IR'LOW)); -- 22 bits imediate value (Max value 4194304)
|
case currentCpuState is
|
case currentCpuState is
|
Line 103... |
Line 104... |
-- Increment program counter (Remember that PC will be update only on the next cycle...
|
-- Increment program counter (Remember that PC will be update only on the next cycle...
|
PC <= PC + conv_std_logic_vector(1, nBits);
|
PC <= PC + conv_std_logic_vector(1, nBits);
|
MemoryDataRdAddr <= PC; -- Warning PC is not 1 yet...
|
MemoryDataRdAddr <= PC; -- Warning PC is not 1 yet...
|
IR <= MemoryDataInput;
|
IR <= MemoryDataInput;
|
MemoryDataReadEn <= '1';
|
MemoryDataReadEn <= '1';
|
|
MemoryDataWriteEn <= '0';
|
nextCpuState <= decode;
|
nextCpuState <= decode;
|
|
|
-- Detect with instruction came from memory, set the number of cycles to execute...
|
-- Detect with instruction came from memory, set the number of cycles to execute...
|
when decode =>
|
when decode =>
|
MemoryDataReadEn <= '0';
|
MemoryDataReadEn <= '0';
|
MemoryDataWriteEn <= '0';
|
MemoryDataWriteEn <= '0';
|
|
|
-- The high attribute points to the highes bit position
|
-- The high attribute points to the highes bit position
|
case opcodeIR is
|
case opcodeIR is
|
when mov_reg | mov_val | add_reg | add_val | sub_reg | and_reg | or_reg | xor_reg | ld_reg | ld_val | stom_reg | stom_val =>
|
when mov_reg | mov_val | add_reg | add_val | sub_reg | and_reg | or_reg | xor_reg =>
|
nextCpuState <= execute;
|
nextCpuState <= execute;
|
cyclesExecute := 1; -- Wait 1 cycles
|
cyclesExecute := 1; -- Wait 1 cycles
|
currInstruction <= IR;
|
currInstruction <= IR;
|
|
|
|
when ld_reg | ld_val | stom_reg | stom_val =>
|
|
nextCpuState <= execute;
|
|
cyclesExecute := 2; -- Wait 2 cycles
|
|
currInstruction <= IR;
|
|
|
when jmp_val | jmpr_val =>
|
when jmp_val | jmpr_val =>
|
nextCpuState <= execute;
|
nextCpuState <= execute;
|
cyclesExecute := 0; -- No Wait cycle
|
cyclesExecute := 0; -- No Wait cycle
|
|
|
-- Invalid instruction (Now will be ignored, but latter should raise a trap
|
-- Invalid instruction (Now will be ignored, but latter should raise a trap
|
Line 141... |
Line 148... |
|
|
when ld_val =>
|
when ld_val =>
|
MemoryDataRdAddr <= "0000000000" & operand_imm;
|
MemoryDataRdAddr <= "0000000000" & operand_imm;
|
MemoryDataReadEn <= '1';
|
MemoryDataReadEn <= '1';
|
|
|
-- STORE r1,10 (Store the value on r1 in the main memory located at address 10)
|
-- STORE r1,10 (Store the value 10 on memory address pointed by r1)
|
when stom_val =>
|
when stom_val =>
|
MemoryDataWrAddr <= "0000000000" & operand_imm;
|
-- And put the imediate value ...
|
|
MemoryDataOut <= "0000000000" & operand_imm;
|
|
if cyclesExecute = 1 then
|
|
-- After the register data is avaible in DataDp we put it's address and
|
|
accDp := DataDp;
|
|
MemoryDataWrAddr <= accDp;
|
|
elsif cyclesExecute = 0 then
|
|
-- strobe in to enter the data
|
MemoryDataWriteEn <= '1';
|
MemoryDataWriteEn <= '1';
|
MemoryDataOut <= DataDp;
|
end if;
|
|
|
when others =>
|
when others =>
|
null;
|
null;
|
end case;
|
end case;
|
|
|
Line 207... |
Line 221... |
MuxDp <= fromMemory;
|
MuxDp <= fromMemory;
|
DpRegFileWriteAddr <= Num2reg(conv_integer(UNSIGNED(operand_reg1)));
|
DpRegFileWriteAddr <= Num2reg(conv_integer(UNSIGNED(operand_reg1)));
|
-- The part that interface with the memory is located on the first process
|
-- The part that interface with the memory is located on the first process
|
nextExState <= writeRegister;
|
nextExState <= writeRegister;
|
|
|
-- STORE r1,10 (Store the value on r1 in the main memory located at address 10)
|
-- STORE r1,10 (Store the value 10 on the main memory pointed by r1)
|
when stom_val =>
|
when stom_val =>
|
MuxDp <= fromRegFileB;
|
MuxDp <= fromRegFileB;
|
DpRegFileReadAddrB <= Num2reg(conv_integer(UNSIGNED(operand_reg1)));
|
DpRegFileReadAddrB <= Num2reg(conv_integer(UNSIGNED(operand_reg1)));
|
DpRegFileReadEnB <= '1';
|
DpRegFileReadEnB <= '1';
|
nextExState <= readRegisterB;
|
|
-- The part that interface with the memory is located on the first process
|
-- The part that interface with the memory is located on the first process
|
nextExState <= readRegisterB;
|
nextExState <= readRegisterB;
|
|
|
-- ADD r2,r0 (See the testDatapath to see how to drive the datapath for this function)
|
-- ADD r2,r0 (See the testDatapath to see how to drive the datapath for this function)
|
when add_reg | sub_reg | and_reg | or_reg | xor_reg =>
|
when add_reg | sub_reg | and_reg | or_reg | xor_reg =>
|