Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
17261 Discussions

Implementing a program counter

Altera_Forum
Honored Contributor II
2,062 Views

Hello! 

 

Im implementing a CPU, so i need a PC (program counter). My instructions are at PC because we dont need to have a memory. 

My problem is: 

 

My BEQ instruction is delayed by one instruction  

(BEQ is like something, if register1 = register2 then jump) 

Example: 

 

move r1,10 <- execute 

move r2,10 <-execute 

beq r1,r2,line5 <-execute 

 

add r1,r2 <- execute and jump 

move r3,r1 

 

line5: sub r1,r2 <- continue... 

 

i dont know why it is executing the next instruciton (add) then jumping. 

Is it a delay problem? 

 

 

thanks in advance. 

I'm Using quartus web edition. 

 

library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; entity PC is port( input : in std_logic_vector(7 downto 0); output : out std_logic_vector(7 downto 0); PCin :in std_logic; address : in std_logic_vector(3 downto 0); PCJR: in std_logic; PCJump: in std_logic; BEQ: in std_logic; BEQ_control : in std_logic; clock : in std_logic; indice : out std_logic_vector(7 downto 0) ); end PC; architecture logic of PC is type instructions is array(0 to 8) of std_logic_vector(7 downto 0); signal ins : instructions; --signal aux : std_logic_vector(7 downto 0); --signal canJump : std_logic; begin --Instructions ins(0) <= "11000001"; ins(1) <= "11001011"; ins(2) <= "00100011"; ins(3) <= "11000010"; ins(4) <= "11011010"; ins(5) <= "11011110"; ins(6) <= "11011001"; ins(7) <= "11000101"; ins(8) <= "01100110"; process(clock) variable ind : integer :=0; begin if(clock'event and clock = '1') then if(PCin = '1') then -- send instruction and increment output <= ins(ind); ind := ind + 1; --indice <= CONV_STD_LOGIC_VECTOR(ind,8); elsif(PCJR = '1') then -- JR ind := CONV_INTEGER(UNSIGNED(input)); elsif(PCJump = '1') then --JUmp ind := CONV_INTEGER(UNSIGNED(address)); elsif(beq = '1') then if(beq_control = '1') then -- PC - 8 ind := ind - (CONV_INTEGER(UNSIGNED(address))); else --PC + 8 ind := ind + (CONV_INTEGER(UNSIGNED(address))); --indice <= CONV_STD_LOGIC_VECTOR(ind,8); end if; end if; --output <= aux; end if; ind := ind; end process; end logic;
0 Kudos
5 Replies
Altera_Forum
Honored Contributor II
884 Views

Using variables is usually a bad coding style. 

I do not understand why many instructions are commented out. Please edit the code above to remove lines that are not meant to be there. 

You do not need the instruction ind := ind; in the end. It does not do anything.
0 Kudos
Altera_Forum
Honored Contributor II
884 Views

Here it is. 

 

But my ind is the position of the array 

i mean like in C vet[i] 

If it isnt good, what can i do ? 

i don't think i can do this with std_logic, or bit. or i can? 

thanks 

 

 

library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; entity PC is port( input : in std_logic_vector(7 downto 0); output : out std_logic_vector(7 downto 0); PCin :in std_logic; address : in std_logic_vector(3 downto 0); PCJR: in std_logic; PCJump: in std_logic; BEQ: in std_logic; BEQ_control : in std_logic; clock : in std_logic; indice : out std_logic_vector(7 downto 0) ); end PC; architecture logic of PC is type instructions is array(0 to 8) of std_logic_vector(7 downto 0); signal ins : instructions; begin --Instructions ins(0) <= "11000001"; ins(1) <= "11001011"; ins(2) <= "00100011"; ins(3) <= "11000010"; ins(4) <= "11011010"; ins(5) <= "11011110"; ins(6) <= "11011001"; ins(7) <= "11000101"; ins(8) <= "01100110"; process(clock) variable ind : integer :=0; begin if(clock'event and clock = '1') then if(PCin = '1') then -- send instruction and increment output <= ins(ind); ind := ind + 1; elsif(PCJR = '1') then -- JR ind := CONV_INTEGER(UNSIGNED(input)); elsif(PCJump = '1') then --JUmp ind := CONV_INTEGER(UNSIGNED(address)); elsif(beq = '1') then if(beq_control = '1') then -- PC - 8 ind := ind - (CONV_INTEGER(UNSIGNED(address))); else --PC + 8 ind := ind + (CONV_INTEGER(UNSIGNED(address))); end if; end if; end if; end process; end logic;
0 Kudos
Altera_Forum
Honored Contributor II
884 Views

I asked you to edit the first post, not to post a second one :) 

And now you removed so much code that I doubt that the code does anything at all.
0 Kudos
Altera_Forum
Honored Contributor II
884 Views

I dont quite understand your problem. From your code the output only changes when PCin is high, and it outputs whatever the last instruction was.

0 Kudos
Altera_Forum
Honored Contributor II
884 Views

This PC entity always send to my CPU the next instruction

0 Kudos
Reply