Where do you save the counter? And how and when is it updated?
I just changed it to a signal, which gives other interesting effects
now.
signal Counter : std_ulogic_vector(2 downto 0);
Hm, what does it when executing the very first command, when there was
none before?
I don't know your code, so I'm just guessing: Simulation for the first
cycle starts, the driver for RegOpcode is attached, and the process for
the controller is evaluated (still with the old opcode). The case
selects the opcode and the current cycle, which is 1. Maybe you are
updating the counter value *now*, so that you are in cycle 2. In the
next delta cycle, the right opcode is loaded, but the prol is in the
wrong cycle. This would explain the behaviour you are describing.
It would be cool if you posted some code, to have a look at it...
Yes, now that I changed the counter variable to a signal, it seems
that while in Cycle 2 it reads 1 from the Counter. I made a seperate
process that takes care of updating the counter:
c: process(ZuluClk, Reset) is
begin
if (Reset = '1') then
Counter <= "001";
elsif (ZuluClk'event and ZuluClk = '1') then
if (LastCycle = '0') then
Counter <= (Counter(1), Counter(0), '0');
else
Counter <= "001";
end if;
end if;
end process;
(LastCycle is a signal that is set to '1' when a command is in the
last cycle that it needs)
Then follows the main process, which sets the signals for the
datapath. I've stripped most opcode parts from this one, they're all
similiar and I don't want my teacher to see that I'm posting working
code on here; I'm pretty sure that he reads the group, too
Just a few minutes ago, I was thinking it over again and wondered if
the resets of the various signals in the beginning of each cycle would
be the reason for some of the problems, because in the first delta
cycle they'd be zero while in the next deltas they could change back
to '1' or so. (I've marked them in the code so you know which part I
mean)
main: process(ZuluClk, Reset, Counter, RegOpCode, LastCycle) is
variable LastCarry, LastZero : std_ulogic;
procedure IncPC is
begin
SelPC <= '1'; -- Select PC as SideA
AluFunc <= "0011"; -- Choose INC as function
ClkEnPc <= '1'; -- Enable writing of RegPC
end procedure;
procedure FetchOpc is
begin
SelAddr <= '0'; -- Select PC as memory address
ClkEnOpCode <= '1'; -- Prepare RegOpCode to save new opcode
end procedure;
procedure LogicalSave is
begin
SelLoad <= '0'; -- Select aluresult as RegFile input
ClkEnRegFile <= '1'; -- Tell RegFile to save
end procedure;
begin
if (Reset='1') then
LastCycle <= '1';
SetRdStrobe <= '0';
SetWrStrobe <= '0';
ResetC <= '1';
elsif (ZuluClk'event and ZuluClk='1') then
-- I MEANT THE RESETS FROM HERE
ClkEnPC <= '0';
ClkEnRegFile <= '0';
ClkEnOpcode <= '0';
SelPC <= '0';
SelAddr <= '0';
SelLoad <= '0';
-- pragma translate_off
ClkEnMem <= '0';
-- pragma translate_on
SetRdStrobe <= '0';
SetWrStrobe <= '0';
-- ... TO HERE
if (LastCycle = '1' and Counter = "001") then
LastCycle <= '0';
end if;
case RegOpCode is
when opcSleep =>
LegalOpCodePresent <= '1';
case Counter is
when "001" =>
LastCycle <= '1';
-- pragma translate_off
report ("Ending Simulation upon opcSLEEP") severity
failure;
-- pragma translate_on
when "010" => null;
when "100" => null;
when others =>
-- pragma translate_off
report("Invalid Counter value") severity error;
-- pragma translate_on
end case;
when opcLOADI =>
LegalOpCodePresent <= '1';
case Counter is
when "001" =>
IncPC;
SetRdStrobe <= '1'; -- Tell the memory to send
when "010" =>
SelAddr <= '0'; -- Select PC as memory adress
SelLoad <= '1'; -- Select memory data as RegFile
input
ClkEnRegFile <= '1'; -- Prepare regfile to save
loaded value
IncPC;
SetRdStrobe <= '1'; -- Tell the memory to send (for
fetch)
when "100" =>
FetchOpc;
LastCycle <= '1';
when others =>
-- pragma translate_off
report("Invalid Counter value") severity error;
-- pragma translate_on
end case;
when opcSTORE =>
LegalOpCodePresent <= '1';
case Counter is
when "001" =>
IncPC;
SetWrStrobe <= '1'; -- Tell the memory to save
when "010" =>
SelAddr <= '1'; -- Select SideB as memory adress
SetRdStrobe <= '1'; -- Tell the memory to send (for
fetch)
when "100" =>
FetchOpc;
LastCycle <= '1';
when others =>
-- pragma translate_off
report("Invalid Counter value") severity error;
-- pragma translate_on
end case;
when opcADD =>
LegalOpCodePresent <= '1';
case Counter is
when "001" =>
IncPC;
SetRdStrobe <= '1'; -- Tell the memory to send (for
fetch)
when "010" =>
LogicalSave;
CarryIn <= '0'; -- Don't add a carry
ALUFunc <= "0101"; -- Select a+b+c as aluresult
FetchOpc;
LastCycle <= '1';
when "100" =>
null;
when others =>
-- pragma translate_off
report("Invalid Counter value") severity error;
-- pragma translate_on
end case;
... more cases with other commands
when others =>
if (RegOpCode/=opcNOP) then
LegalOpCodePresent <= '0';
-- pragma translate_off
report ("Illegal Opcode") severity warning;
-- pragma translate_on
else
LegalOpCodePresent <= '1';
end if;
case Counter is
when "001" =>
if (ResetC ='0') then
IncPC;
else
ResetC <= '0';
end if;
SetRdStrobe <= '1'; -- Tell the memory to send (for
fetch)
when "010" =>
FetchOpc;
LastCycle <= '1';
when "100" => null;
when others =>
-- pragma translate_off
report("Invalid Counter value") severity error;
-- pragma translate_on
end case;
end case;
end if;
end process;
end architecture;