Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Simple VHDL Problem with synchronous/asynchronous logic

Status
Not open for further replies.

Richard29

Member level 1
Joined
Oct 26, 2010
Messages
37
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Activity points
1,646
Hi all,

I am really stuck now. The following module is working fine in simulation but does not work properly in hardware. It is so simple, but I can't figure out why it is not working. Essentially, this module gets two input operands (op1, op2), two comand signals (fu_op, fu_imm) and a clock. The following two evaluations
are executed in consecutive clock cycles:

S0 (x) tx <= x;
r <= just some simple xor, or, and with input x

F0(tx, x, y) r <= just some simple xor, or, and with input x, y and also tx!

I guess that somehow the passing of tx to F0 is not working. Is there anything wrong how I try to handle the case of tx, might I have forgotten it in the sensitivity list?

Many thanks for your input!


Code:
entity test_module is
port
(
  op1    : in  std_logic_vector(31 downto 0);      -- First input operand
  op2    : in  std_logic_vector(31 downto 0);      -- Second input operand
  fu_op  : fu_op_type;                             -- Opcode
  fu_imm : in std_logic_vector(7 downto 0);        -- Immediate
  clk    : in  std_logic;                          -- clock
  res    : out std_logic_vector(31 downto 0)       -- Result
);
end;

architecture rtl of test_module is

  type res_sel_type is (PASS, S0, F0); 
                                                                                                                       
  signal res_sel  : res_sel_type;
  signal load     : std_logic := '0';
  
  signal tx       : std_logic_vector(31 downto 0) := (others => '0');
  
   
  procedure S0_proc
  (
    signal a : in  std_logic_vector(31 downto 0);
    signal r : out std_logic_vector(31 downto 0)
  )
  is
    constant Z : std_logic_vector(31 downto 0) := (others => '0');      
    variable res : std_logic_vector(31 downto 0);
  begin
    
    r := ( a(6 downto 0) & a(31 downto 7) ) xor ( a(17 downto 0) & a(31 downto 18) ) xor ( Z(2 downto 0) & a(31 downto 3) );

  end;
  
  procedure F0_proc
  (
    signal a : in  std_logic_vector(31 downto 0);
    signal b : in  std_logic_vector(31 downto 0);
    signal c : in  std_logic_vector(31 downto 0);
    signal r : out std_logic_vector(31 downto 0)
  )
  is
    variable res : std_logic_vector(31 downto 0);
  begin
      
    r <= ( a and b ) or ( ( a or b ) and c ) ;

  end;
  
begin

  -- Decode opcode
  dec_op: process (fu_op, fu_imm)
  
    variable tmp  : res_sel_type;
    variable ld   : std_logic;
    
  begin
    
    -- Default value
    tmp  := PASS;
    ld   := '0';
    
    if (fu_op = FU_FPGA) then
    
      case fu_imm is
  	   
       -- compute S0, store first operand 
  		 when S0 =>
  			ld  := '1';  		 
  			tmp := S0;
  			        
       -- compute F0 
   		 when F0 =>
  			ld  := '0';  		 
  			tmp := F0;	               	        			
                                                                                                                                					
  		 when others =>
  			-- Leave default values
  		 
  		 end case;
  		 
  		 res_sel  <= tmp;
                 load     <= ld;       
  	end if;	    
    
  end process;
  
  -- Selection of output
  sel_out: process (res_sel, op1, op2) 
  begin
    
    case res_sel is
	 
	   when S0 => 
      S0_proc(op1, res);  
	         
	    when F0 =>
	F0_proc(tx, op1, op2, res); 	
              
    end case;
    
  end process;
  
  
  sync: process(clk)
	begin	    
	 if clk'event and clk = '1' then
	      if load = '1' then  
	         tx <= op1;
	      end if;      
	 end if;
  end process;  
  
end rtl;
 
Last edited:

S0_proc uses the constant Z, but that value isn't passed in. I don't see where you define the quatities "FPGA_FO" and "FPGA_SO" You should get an error when you use a value that isnt' defined. Same, I think, for "FU_FPGA".
 

Thanks for your feedback. Actually, the FPGA_F0 and FPGA_S0 was a copy and paste error, should be fine now. I can run the current version in hardware, and the result for S0 is fine, the problem is only the computation of F0. I am not sure what is going wrong there, do I need to use tx somehow in a sensitivity list?
 

First off, please use the CODE tags rather than the QUOTE tags when posting code, it formats it much better on the forum.

Secondly - you've a load of latches. There is no action to take when res_sel is PASS, so res holds its old value when res_sel = PASS. latches are generally bad because you cannot garantee timing with them. With this code, the output RES will only change when res_sel (which depends on fu_imm and fu_op) changes from PASS to S0 or F0 (because the clock input of the register will be a gated version of the two bits in res_sel). Im guessing your output is changing at the wrong time?

---------- Post added at 19:36 ---------- Previous post was at 19:34 ----------

A quick solution would be to synchronise everything. FPGAs dont like asynchronous logic very much, and latches are bad.

---------- Post added at 19:43 ---------- Previous post was at 19:36 ----------

Also, you have several syntax errors.

The warnings I got in Quartus were as I expected, so expect bad behaviour:
Warning (10631): VHDL Process Statement warning at test_module.vhd(59): inferring latch(es) for signal or variable "res_sel", which holds its previous value in one or more paths through the process
Warning (10631): VHDL Process Statement warning at test_module.vhd(59): inferring latch(es) for signal or variable "load", which holds its previous value in one or more paths through the process

---------- Post added at 19:44 ---------- Previous post was at 19:43 ----------

So many errors infact - are you sure this is the correct code?
 

Thanks for your feedback. I edited the posting to include the code in the proper tag, sorry for mixing that up. There might be the one or other syntax
error since I have excluded some special cases, but the overall design can be properly syntesized. That is a bit surprising with the latches, I thought when
I set their default value (as I did) in the process, then latches are avoided.... Have to have a look at this again.
 

You're probably going to need to include a "reset" signal and use it to initialize your variables, like 'Z' and 'Tx' and make those signals registers which get setup in the clock process. Your compiler probably ingnores the initialization you are doing in the signal declaration.
 

The big problem is this line:

r <= ( a(6 downto 0) & a(31 downto 7) ) xor ( a(17 downto 0) & a(31 downto 1 ) xor ( Z(2 downto 0) & a(31 downto 3) ) ) ;

Error (10344): VHDL expression error at test_module.vhd(37): expression has 49 elements, but must have 32 elements


And the case statement in the "sel_out" process is not complete, so wont compile.
Please repost all of your code.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top