EmbDev.net

Forum: FPGA, VHDL & Verilog For loop in VHDL


Author: Chris Regform (regform)
Posted on:

Rate this post
0 useful
not useful
Good day,

I am trying to use a for loop in VHDL to create an SLL "calculator" (for 
lack of a better term) as part of a MIPS assembly system.

I get the following errors:

# ** Error: C:/Users/Christian/Documents/ift 1227/dev 5 
Mips/one_cycle_mips.vhd(179): near ":=": expecting ':'
# ** Error: C:/Users/Christian/Documents/ift 1227/dev 5 
Mips/one_cycle_mips.vhd(184): No feasible entries for infix operator 
"sll".
# ** Error: C:/Users/Christian/Documents/ift 1227/dev 5 
Mips/one_cycle_mips.vhd(184): Type error resolving infix expression 
"sll" as type ieee.std_logic_1164.STD_LOGIC_VECTOR.

Here is the part of the code that does not work. I have compiled my code 
one step at a time, so I know that everything else works.
 shift_tmp <=  RTdata;
 
process (shift, RTdata)
 variable i := integer range 0 to 31;
 i:=0;
 
begin
  for i in 0 to (to_integer(unsigned(shift))) loop
    shift_tmp <= shift_tmp sll 1;
  end loop;
 end process;
 
shift_out <=  shift_tmp;


Here is the entire code:
-- mips.vhd
-- From Section 7.6 of Digital Design & Computer Architecture
-- Updated to VHDL 2008 26 July 2011 David_Harris@hmc.edu
-- Modified at U de Montreal 2015

library IEEE; 
use IEEE.STD_LOGIC_1164.all; use IEEE.NUMERIC_STD.all; 

entity One_Cycle_MIPS is
  signal RTdata, dataadr:    STD_LOGIC_VECTOR(31 downto 0);
  signal clk, reset,  memwrite: STD_LOGIC := '0';
  signal pc, instr, 
         readdata: STD_LOGIC_VECTOR(31 downto 0);
 
------------Data Memory----------------------------
  type ramtype is array (63 downto 0) of STD_LOGIC_VECTOR(31 downto 0);
  signal mem: ramtype;  
----============Pgm to execute==================================
  type MemInstType is array (0 to 63) of STD_LOGIC_VECTOR(31 downto 0);
  constant MemInst: MemInstType := (
    X"20020005",   -- main:   addi $2, $0, 5
    X"2003000c",   --         addi $3, $0, 12
    X"2067fff7",   --         addi $7, $3, −9
    X"00e22025",   --         or $4, $7, $2
    X"00642824",   --         and $5, $3, $4
    X"00a42820",   --         add $5, $5, $4
    X"10a7000a",   --         beq $5, $7, end
    X"0064202a",   --         slt $4, $3, $4
    X"10800001",   --         beq $4, $0, around 
    X"20050000",   --         addi $5, $0, 0
    X"00e2202a",   -- around: slt $4, $7, $2
    X"00853820",   --         add $7, $4, $5
    X"00e23822",   --         sub $7, $7, $2
    X"ac670044",   --         sw $7, 68($3)
    X"8c020050",   --         lw $2, 80($0)        
    X"08000011",   --         j end
    X"20020001",   --         addi $2, $0, 1
    X"ac020054",   -- end:    sw $2, 84($0)
    others => X"00000000");  

-- Signaux MIPS----------------------------------------------
  signal memtoreg, alusrc, regdst, regwrite, pcsrc: STD_LOGIC;
  signal jump, adr3contr: STD_LOGIC_VECTOR(1 downto 0);
  signal zero: STD_LOGIC;
  signal alucontrol: STD_LOGIC_VECTOR(2 downto 0);
  
 -- Format Instructions-------------------------------------------------
  alias op    : std_logic_vector (5 downto 0) is instr(31 downto 26);
  alias funct : std_logic_vector (5 downto 0) is instr(5 downto 0);
  alias rs    : std_logic_vector (4 downto 0) is instr(25 downto 21);
  alias rt    : std_logic_vector (4 downto 0) is instr(20 downto 16);
  alias rd    : std_logic_vector (4 downto 0) is instr(15 downto 11);
  alias imm   : std_logic_vector (15 downto 0) is instr(15 downto 0);
  alias shift : std_logic_vector (4 downto 0) is instr(10 downto 6);

------Signaux Controller-----------------------------------
  signal aluop:  STD_LOGIC_VECTOR(1 downto 0);
  signal branch: STD_LOGIC; 
 -----Signaux Maindec---------------------------
  signal controls: STD_LOGIC_VECTOR(11 downto 0);
 
 --Signaux DATAPATH---------------------------------  
  signal aluout, lui, wd3, ori, shift_tmp, shift_out: std_logic_vector (31 downto 0);
  signal writereg, adr3:   STD_LOGIC_VECTOR(4 downto 0);
  signal PCJump, pcnext, pcnextbr, pcplus4, PCBranch, SignImm, SignImmShiftLeft2:           
          STD_LOGIC_VECTOR(31 downto 0);
  signal srca, srcb, result: STD_LOGIC_VECTOR(31 downto 0);  

-- Signaux Register File----------------------------------------  
  type RFtype is array (31 downto 0) of STD_LOGIC_VECTOR(31 downto 0);
  signal RF: RFtype;
  
end;
--================ARCHITECTURE=========================================
architecture test of One_Cycle_MIPS is
begin  
  clk <= NOT clk after 5 ns; -- Generate clock with 10 ns period
  reset <= '0', '1' after 1 ns, '0' after 2 ns;
  
---Instruction Memory----------------------------------------------
  instr <= MemInst(to_INTEGER(unsigned(pc(7 downto 2))));
  
------Data Memory R/W----------------------------------------------
  process (clk) is
  begin
   if clk'event and clk = '1' then
     if (memwrite = '1') then mem(to_integer(unsigned(dataadr(7 downto 2)))) <= RTdata;
     end if;
   end if;   
  end process;

  readdata <= mem(to_integer(unsigned(dataadr(7 downto 2))));

---===============mips========================================  
-- Controller----------------------
maindec:  process(op, funct) begin
    case op is
      when "000000" => 
       if funct = "001000" then controls <= "000000100000"; -- JR
       elsif funct = "000000" then controls <= "110000000011"; -- SLL
       else controls <= "110000001000"; -- RTYPE
      end if;
      when "100011" => controls <= "101001000000"; -- LW
      when "101011" => controls <= "001010000000"; -- SW
      when "000100" => controls <= "000100000100"; -- BEQ
      when "000010" => controls <= "000000010000"; -- J
      when "001000" => controls <= "101000000100"; -- ADDI
      when "001111" => controls <= "100000000001"; -- LUI
      when "001101" => controls <= "100000001010"; -- ORI
      when "000011" => controls <= "100000100000"; -- JAL
      when others   => controls <= "------------"; -- illegal op
    end case;
  end process;
  (regwrite, regdst, alusrc, branch, memwrite, memtoreg, jump(1),jump(0), 
   aluop(1),aluop(0), adr3contr(1), adr3contr(0)) <= controls; 
  
Aludec: process(aluop, funct) begin
    case aluop is
      when "00" => alucontrol <= "010"; -- add (for lw/sw/addi)
      when "01" => alucontrol <= "110"; -- sub (for beq)
      when others => case funct is      -- R-type instructions
                    when "100000" => alucontrol <= "010"; -- add 
                    when "100010" => alucontrol <= "110"; -- sub
                    when "100100" => alucontrol <= "000"; -- and
                    when "100101" => alucontrol <= "001"; -- or
                    when "101010" => alucontrol <= "111"; -- slt
                    when others   => alucontrol <= "---"; -- ???
                    end case;
    end case;
  end process;  
  
  pcsrc <= branch and zero;
  
 --===================DATAPATH======================================
 -- next PC logic----------------------------
  SignImm <= X"ffff" & imm when imm(15) = '1' else X"0000" & imm; 
  SignImmShiftLeft2 <= SignImm(29 downto 0) & "00";
  
  Plus4: pcplus4 <= STD_LOGIC_VECTOR(unsigned(pc) + 4); 
  BTA: PCBranch <= std_logic_vector(signed(pcplus4) + signed(SignImmShiftLeft2));
  JTA: PCJump <= pcplus4(31 downto 28) & instr(25 downto 0) & "00";
  
  pcnextbr <= PCBranch when pcsrc = '1' else pcplus4;  
  pcnext   <= PCJump when jump = "01" else pcnextbr when jump = "00" else srca when jump = "10";

  updatePC: process(clk, reset) begin
    if reset ='1' then  PC <= (others => '0');
    elsif rising_edge(clk) then
      PC <= pcnext;
    end if;
  end process;
  
-- Register File Logic----------------------------
 srca <= (others => '0') when (to_integer(unsigned(rs)) = 0) -- register 0 holds 0
                     else RF(to_integer(unsigned(rs)));
 RTdata <= (others => '0')  when (to_integer(unsigned(rt)) = 0) 
                     else RF(to_integer(unsigned(rt)));
 srcb <= SignImm when (alusrc = '1') else RTdata; 

 lui <= imm & X"0000";
 ori <= X"0000" & imm;

 wd3 <= result when adr3contr = "00" else lui when adr3contr = "01" 
  else (ori OR srca) when adr3contr = "10" else shift_out when adr3contr = "11"; -- DATA 
 adr3 <= "11111" when jump = "10" else writereg; --jal $ra = 31
 writereg <= rd when regdst = '1' else rt;
 result <= readdata when memtoreg = '1' else aluout;
 
 process(clk) begin
    if rising_edge(clk) then
       if regwrite = '1' then RF(to_integer(unsigned(adr3))) <= wd3;
       end if;
    end if;
 end process;

 shift_tmp <=  RTdata;
 
process (shift, RTdata)
 variable i := integer range 0 to 31;
 i:=0;
 
begin
  for i in 0 to (to_integer(unsigned(shift))) loop
    shift_tmp <= shift_tmp sll 1;
  end loop;
 end process;
 
shift_out <=  shift_tmp;{-- mips.vhd
-- From Section 7.6 of Digital Design & Computer Architecture
-- Updated to VHDL 2008 26 July 2011 David_Harris@hmc.edu
-- Modified at U de Montreal 2015

library IEEE; 
use IEEE.STD_LOGIC_1164.all; use IEEE.NUMERIC_STD.all; 

entity One_Cycle_MIPS is
  signal RTdata, dataadr:    STD_LOGIC_VECTOR(31 downto 0);
  signal clk, reset,  memwrite: STD_LOGIC := '0';
  signal pc, instr, 
         readdata: STD_LOGIC_VECTOR(31 downto 0);
 
------------Data Memory----------------------------
  type ramtype is array (63 downto 0) of STD_LOGIC_VECTOR(31 downto 0);
  signal mem: ramtype;  
----============Pgm to execute==================================
  type MemInstType is array (0 to 63) of STD_LOGIC_VECTOR(31 downto 0);
  constant MemInst: MemInstType := (
    X"20020005",   -- main:   addi $2, $0, 5
    X"2003000c",   --         addi $3, $0, 12
    X"2067fff7",   --         addi $7, $3, −9
    X"00e22025",   --         or $4, $7, $2
    X"00642824",   --         and $5, $3, $4
    X"00a42820",   --         add $5, $5, $4
    X"10a7000a",   --         beq $5, $7, end
    X"0064202a",   --         slt $4, $3, $4
    X"10800001",   --         beq $4, $0, around 
    X"20050000",   --         addi $5, $0, 0
    X"00e2202a",   -- around: slt $4, $7, $2
    X"00853820",   --         add $7, $4, $5
    X"00e23822",   --         sub $7, $7, $2
    X"ac670044",   --         sw $7, 68($3)
    X"8c020050",   --         lw $2, 80($0)        
    X"08000011",   --         j end
    X"20020001",   --         addi $2, $0, 1
    X"ac020054",   -- end:    sw $2, 84($0)
    others => X"00000000");  

-- Signaux MIPS----------------------------------------------
  signal memtoreg, alusrc, regdst, regwrite, pcsrc: STD_LOGIC;
  signal jump, adr3contr: STD_LOGIC_VECTOR(1 downto 0);
  signal zero: STD_LOGIC;
  signal alucontrol: STD_LOGIC_VECTOR(2 downto 0);
  
 -- Format Instructions-------------------------------------------------
  alias op    : std_logic_vector (5 downto 0) is instr(31 downto 26);
  alias funct : std_logic_vector (5 downto 0) is instr(5 downto 0);
  alias rs    : std_logic_vector (4 downto 0) is instr(25 downto 21);
  alias rt    : std_logic_vector (4 downto 0) is instr(20 downto 16);
  alias rd    : std_logic_vector (4 downto 0) is instr(15 downto 11);
  alias imm   : std_logic_vector (15 downto 0) is instr(15 downto 0);
  alias shift : std_logic_vector (4 downto 0) is instr(10 downto 6);

------Signaux Controller-----------------------------------
  signal aluop:  STD_LOGIC_VECTOR(1 downto 0);
  signal branch: STD_LOGIC; 
 -----Signaux Maindec---------------------------
  signal controls: STD_LOGIC_VECTOR(11 downto 0);
 
 --Signaux DATAPATH---------------------------------  
  signal aluout, lui, wd3, ori, shift_tmp, shift_out: std_logic_vector (31 downto 0);
  signal writereg, adr3:   STD_LOGIC_VECTOR(4 downto 0);
  signal PCJump, pcnext, pcnextbr, pcplus4, PCBranch, SignImm, SignImmShiftLeft2:           
          STD_LOGIC_VECTOR(31 downto 0);
  signal srca, srcb, result: STD_LOGIC_VECTOR(31 downto 0);  

-- Signaux Register File----------------------------------------  
  type RFtype is array (31 downto 0) of STD_LOGIC_VECTOR(31 downto 0);
  signal RF: RFtype;
  
end;
--================ARCHITECTURE=========================================
architecture test of One_Cycle_MIPS is
begin  
  clk <= NOT clk after 5 ns; -- Generate clock with 10 ns period
  reset <= '0', '1' after 1 ns, '0' after 2 ns;
  
---Instruction Memory----------------------------------------------
  instr <= MemInst(to_INTEGER(unsigned(pc(7 downto 2))));
  
------Data Memory R/W----------------------------------------------
  process (clk) is
  begin
   if clk'event and clk = '1' then
     if (memwrite = '1') then mem(to_integer(unsigned(dataadr(7 downto 2)))) <= RTdata;
     end if;
   end if;   
  end process;

  readdata <= mem(to_integer(unsigned(dataadr(7 downto 2))));

---===============mips========================================  
-- Controller----------------------
maindec:  process(op, funct) begin
    case op is
      when "000000" => 
       if funct = "001000" then controls <= "000000100000"; -- JR
       elsif funct = "000000" then controls <= "110000000011"; -- SLL
       else controls <= "110000001000"; -- RTYPE
      end if;
      when "100011" => controls <= "101001000000"; -- LW
      when "101011" => controls <= "001010000000"; -- SW
      when "000100" => controls <= "000100000100"; -- BEQ
      when "000010" => controls <= "000000010000"; -- J
      when "001000" => controls <= "101000000100"; -- ADDI
      when "001111" => controls <= "100000000001"; -- LUI
      when "001101" => controls <= "100000001010"; -- ORI
      when "000011" => controls <= "100000100000"; -- JAL
      when others   => controls <= "------------"; -- illegal op
    end case;
  end process;
  (regwrite, regdst, alusrc, branch, memwrite, memtoreg, jump(1),jump(0), 
   aluop(1),aluop(0), adr3contr(1), adr3contr(0)) <= controls; 
  
Aludec: process(aluop, funct) begin
    case aluop is
      when "00" => alucontrol <= "010"; -- add (for lw/sw/addi)
      when "01" => alucontrol <= "110"; -- sub (for beq)
      when others => case funct is      -- R-type instructions
                    when "100000" => alucontrol <= "010"; -- add 
                    when "100010" => alucontrol <= "110"; -- sub
                    when "100100" => alucontrol <= "000"; -- and
                    when "100101" => alucontrol <= "001"; -- or
                    when "101010" => alucontrol <= "111"; -- slt
                    when others   => alucontrol <= "---"; -- ???
                    end case;
    end case;
  end process;  
  
  pcsrc <= branch and zero;
  
 --===================DATAPATH======================================
 -- next PC logic----------------------------
  SignImm <= X"ffff" & imm when imm(15) = '1' else X"0000" & imm; 
  SignImmShiftLeft2 <= SignImm(29 downto 0) & "00";
  
  Plus4: pcplus4 <= STD_LOGIC_VECTOR(unsigned(pc) + 4); 
  BTA: PCBranch <= std_logic_vector(signed(pcplus4) + signed(SignImmShiftLeft2));
  JTA: PCJump <= pcplus4(31 downto 28) & instr(25 downto 0) & "00";
  
  pcnextbr <= PCBranch when pcsrc = '1' else pcplus4;  
  pcnext   <= PCJump when jump = "01" else pcnextbr when jump = "00" else srca when jump = "10";

  updatePC: process(clk, reset) begin
    if reset ='1' then  PC <= (others => '0');
    elsif rising_edge(clk) then
      PC <= pcnext;
    end if;
  end process;
  
-- Register File Logic----------------------------
 srca <= (others => '0') when (to_integer(unsigned(rs)) = 0) -- register 0 holds 0
                     else RF(to_integer(unsigned(rs)));
 RTdata <= (others => '0')  when (to_integer(unsigned(rt)) = 0) 
                     else RF(to_integer(unsigned(rt)));
 srcb <= SignImm when (alusrc = '1') else RTdata; 

 lui <= imm & X"0000";
 ori <= X"0000" & imm;

 wd3 <= result when adr3contr = "00" else lui when adr3contr = "01" 
  else (ori OR srca) when adr3contr = "10" else shift_out when adr3contr = "11"; -- DATA 
 adr3 <= "11111" when jump = "10" else writereg; --jal $ra = 31
 writereg <= rd when regdst = '1' else rt;
 result <= readdata when memtoreg = '1' else aluout;
 
 process(clk) begin
    if rising_edge(clk) then
       if regwrite = '1' then RF(to_integer(unsigned(adr3))) <= wd3;
       end if;
    end if;
 end process;

 shift_tmp <=  RTdata;
 
process (shift, RTdata)
 variable i := integer range 0 to 31;
 i:=0;
 
begin
  for i in 0 to (to_integer(unsigned(shift))) loop
    shift_tmp <= shift_tmp sll 1;
  end loop;
 end process;
 
shift_out <=  shift_tmp;

 -- ALU logic -------------------------------------------------------
  process(alucontrol, srca, srcb) 
   variable sum: STD_LOGIC_VECTOR(31 downto 0);
  begin
    if alucontrol(2) = '0' 
         then sum  := STD_LOGIC_VECTOR(signed(srca) + signed(srcb)); 
         else sum  := STD_LOGIC_VECTOR(signed(srca) - signed(srcb)); 
    end if;              
    case alucontrol(2 downto 0) is
      when "000"   => aluout <= srca and srcb; 
      when "001"   => aluout <= srca or srcb; 
      when "010"|"110"   => aluout <= sum; 
      when "111"   => aluout <= (0 => sum(31), others => '0'); 
      when others => aluout <= (others => 'X'); 
    end case;
 end process;
  
  zero <= '1' when (aluout = X"00000000") else '0';
  dataadr <= aluout;
  
--========================VERIFICATION=====================================  
  -- check that 7 gets written to address 84 at end of program
process (clk) begin
  if (clk'event and clk = '0' and memwrite = '1') then
     if (to_integer(unsigned(dataadr)) = 84 and 
         to_integer(unsigned(RTdata)) = 7) then 
      report "NO ERRORS: Simulation succeeded" severity failure;
     elsif (to_integer(unsigned(dataadr)) /= 80) then 
       report "Simulation failed" severity failure;
     end if;
   end if;
end process;
end;
}

 -- ALU logic -------------------------------------------------------
  process(alucontrol, srca, srcb) 
   variable sum: STD_LOGIC_VECTOR(31 downto 0);
  begin
    if alucontrol(2) = '0' 
         then sum  := STD_LOGIC_VECTOR(signed(srca) + signed(srcb)); 
         else sum  := STD_LOGIC_VECTOR(signed(srca) - signed(srcb)); 
    end if;              
    case alucontrol(2 downto 0) is
      when "000"   => aluout <= srca and srcb; 
      when "001"   => aluout <= srca or srcb; 
      when "010"|"110"   => aluout <= sum; 
      when "111"   => aluout <= (0 => sum(31), others => '0'); 
      when others => aluout <= (others => 'X'); 
    end case;
 end process;
  
  zero <= '1' when (aluout = X"00000000") else '0';
  dataadr <= aluout;
 


Any help is appreciated!!

Thanks,

Chris

Author: Bitflüsterer (Guest)
Posted on:

Rate this post
0 useful
not useful
Nearly unbelievable. You wrote that code and you are not able to find a 
simple syntax error? :-)
I got no hint, which your local time is, but I would say, it's 
definately late there. Go to bed, sleep well and have another look 
tomorrow.

By the way: Please post long code as attachment, not inline.

Author: Chris Regform (regform)
Posted on:

Rate this post
0 useful
not useful
Update:

I have changed to the following code:

process (shift, RTdata)
 variable i : integer range 0 to 31;
 
begin
  for i in 0 to (to_integer(unsigned(shift))) loop
    shift_tmp <= shift_tmp(30 downto 0) & "0";
  end loop;
 end process;
 
shift_out <=  shift_tmp;


This reduces the error to
Error: C:/Users/Christian/Documents/ift 1227/dev 5 
Mips/one_cycle_mips.vhd(187): near "EOF": syntax error

P.S. - No I have not noticed the syntax error, I have been programming 
in VHDL for about six weeks, so what might be simple for you might not 
be for me...
:0)

Author: Bitflüsterer (Guest)
Posted on:

Rate this post
0 useful
not useful
I thought it was due to a lack of sound sleep.

However, an architecture, as it has a 'begin' must have an end as well. 
:-) I dont see any other reason which may cause syntax errors at the end 
of your file; as I take the code from your first post as still valid.

Author: Bitflüsterer (Guest)
Posted on:

Rate this post
0 useful
not useful
Btw: Syntax errors are not a matter of knowledge but of memory, so far 
as I am concerned. It's like with good chess players. Most of the time 
they dont calculate but compare patterns.

Author: Chris Regform (regform)
Posted on:

Rate this post
0 useful
not useful
Thanks, I managed to figure it out.
And you weren't wrong about the lack of sleep!
:)

Reply

Entering an e-mail address is optional. If you want to receive reply notifications by e-mail, please log in.

Rules — please read before posting

  • Post long source code as attachment, not in the text
  • Posting advertisements is forbidden.

Formatting options

  • [c]C code[/c]
  • [avrasm]AVR assembler code[/avrasm]
  • [vhdl]VHDL code[/vhdl]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]




Bild automatisch verkleinern, falls nötig
Note: the original post is older than 6 months. Please don't ask any new questions in this thread, but start a new one.