Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
17268 Discussions

Implementing a program counter

Altera_Forum
Honored Contributor II
2,075 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
897 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
897 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
897 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
897 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
897 Views

This PC entity always send to my CPU the next instruction

0 Kudos
Reply