cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
adrialex
Visitor
Visitor
8,280 Views
Registered: ‎08-05-2009

synthesizing problem

i made a vhdl code and tried to synthesize it at post-route simulation. the waveform i got was very different from my behavioral waveform, which was perfectly fine. could anyone give me tips on how to recode my program? i used a seperate process for detecting the clock and reset  from changing my signals and outputs. thank you
0 Kudos
18 Replies
mcgett
Xilinx Employee
Xilinx Employee
8,276 Views
Registered: ‎01-03-2008

Your post doesn't have any significant information on what the problem is.   The only suggestion that I can offer is to read the synthesis report file and review every warning that was reported.
------Have you tried typing your question into Google? If not you should before posting.
Too many results? Try adding site:www.xilinx.com
0 Kudos
adrialex
Visitor
Visitor
8,261 Views
Registered: ‎08-05-2009

for example i have this code. it runs perfectly in behavioral but not in post-route simulation. my coding style for all the components of my program is like that. i would like to ask for coding tips so it would be synthesizable because i don't understand the warnings produced after the synthesis.

 

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity multiplier is
    Port ( clk : in  STD_LOGIC;
           rst : in  STD_LOGIC;
           en : in  STD_LOGIC;
           opA : in  STD_LOGIC_VECTOR (3 downto 0);
           opB : in  STD_LOGIC_VECTOR (3 downto 0);
           res : out  STD_LOGIC_VECTOR (7 downto 0);
           done : out  STD_LOGIC);
end multiplier;

architecture Behavioral of multiplier is

    SIGNAL tempA,tempB : STD_LOGIC_VECTOR(3 downto 0);
    SIGNAL cstate,nstate : STD_LOGIC_VECTOR(2 downto 0);
   
    COMPONENT cla_adder
    PORT ( opA : IN  std_logic_vector (3 downto 0);
           opB : IN  std_logic_vector (3 downto 0);
           carry_in : IN  STD_LOGIC;
           sum : OUT  std_logic_vector (3 downto 0);
           carry_out : OUT  STD_LOGIC
            );
    END COMPONENT;
   
    --Inputs
    SIGNAL op_add1 :  std_logic_vector(3 downto 0);
    SIGNAL op_add2 :  std_logic_vector(3 downto 0);
    SIGNAL op_shift1 :  std_logic_vector(3 downto 0);
    SIGNAL op_shift2 :  std_logic_vector(3 downto 0);
   
    --Outputs
    SIGNAL sum_add :  std_logic_vector(3 downto 0);
    SIGNAL carry_out_add :  std_logic;
    SIGNAL d : std_logic;
   
begin
    adding: cla_adder PORT MAP(
        opA => op_add1,
        opB => op_add2,
        carry_in => '0',
        sum => sum_add,
        carry_out => carry_out_add
    );
   
    changes : process(rst,clk,en,op_shift1,op_shift2)
    begin
        if rst = '1' then
            cstate <= "000";
            res <= "00000000";
            done <= '0';
            op_add1 <= "0000";
            tempA <= "0000";
            tempB <= "0000";
        elsif en = '1' then
            tempA <= opA;
            tempB <= opB;
            cstate <= "000";
            op_add1 <= "0000";
            done <= '0';
        else
            if clk'event and clk = '1' then
                cstate <= nstate;
                op_add1 <= op_shift2;
                tempB <= op_shift1;
                if d = '1' then
                    res <= op_shift2 & op_shift1;
                    done <= '1';
                else
                    done <= '0';
                end if;
            end if;
        end if;
    end process;

    instances : process(cstate,en,rst,tempA,tempB,sum_add,carry_out_add,op_shift1,op_shift2)
    begin
        if en = '0' and rst = '0' then
        case cstate is
            when "000" =>
                if tempB(0) = '1' then
                    op_add2 <= tempA;
                    op_shift2 <= carry_out_add & sum_add(3 downto 1);
                    op_shift1 <= sum_add(0) & tempB(3 downto 1);
                    nstate <= "001";
                else
                    op_add2 <= "0000";
                    op_shift2 <= carry_out_add & sum_add(3 downto 1);
                    op_shift1 <= sum_add(0) & tempB(3 downto 1);
                    nstate <= "001";
                end if;
            when "001" =>
                if tempB(0) = '1' then
                    op_add2 <= tempA;
                    op_shift2 <= carry_out_add & sum_add(3 downto 1);
                    op_shift1 <= sum_add(0) & tempB(3 downto 1);
                    nstate <= "010";
                else
                    op_add2 <= "0000";
                    op_shift2 <= carry_out_add & sum_add(3 downto 1);
                    op_shift1 <= sum_add(0) & tempB(3 downto 1);
                    nstate <= "010";
                end if;
            when "010" =>
                if tempB(0) = '1' then
                    op_add2 <= tempA;
                    op_shift2 <= carry_out_add & sum_add(3 downto 1);
                    op_shift1 <= sum_add(0) & tempB(3 downto 1);
                    nstate <= "011";
                else
                    op_add2 <= "0000";
                    op_shift2 <= carry_out_add & sum_add(3 downto 1);
                    op_shift1 <= sum_add(0) & tempB(3 downto 1);
                    nstate <= "011";
                end if;
            when "011" =>
                if tempB(0) = '1' then
                    op_add2 <= tempA;
                    op_shift2 <= carry_out_add & sum_add(3 downto 1);
                    op_shift1 <= sum_add(0) & tempB(3 downto 1);
                    d <= '1';
                    nstate <= "100";
                else
                    op_add2 <= "0000";
                    op_shift2 <= carry_out_add & sum_add(3 downto 1);
                    op_shift1 <= sum_add(0) & tempB(3 downto 1);
                    nstate <= "100";
                    d <= '1';
                end if;
            when others =>
                    d <= '0';
            end case;
        end if;
    end process;

end Behavioral;

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity cla_adder is
    Port ( opA : in  STD_LOGIC_VECTOR (3 downto 0);
           opB : in  STD_LOGIC_VECTOR (3 downto 0);
           carry_in : in  STD_LOGIC;
           sum : out  STD_LOGIC_VECTOR (3 downto 0);
           carry_out : out  STD_LOGIC);
end cla_adder;

architecture Behavioral of cla_adder is
    SIGNAL s0,s1,s2,s3 : STD_LOGIC;
    SIGNAL g0,g1,g2,g3 : STD_LOGIC;
    SIGNAL p0,p1,p2,p3 : STD_LOGIC;
    SIGNAL c0,c1,c2,c3 : STD_LOGIC;
begin
    s0 <= opA(0) XOR opB(0) XOR carry_in;
    g0 <= opA(0) AND opB(0);
    p0 <= opA(0) OR opB(0);
    c0 <= g0 OR (p0 AND carry_in);
   
    s1 <= opA(1) XOR opB(1) XOR c0;
    g1 <= opA(1) AND opB(1);
    p1 <= opA(1) OR opB(1);
    c1 <= g1 OR (p1 AND c0);
   
    s2 <= opA(2) XOR opB(2) XOR c1;
    g2 <= opA(2) AND opB(2);
    p2 <= opA(2) OR opB(2);
    c2 <= g2 OR (p2 AND c1);
   
    s3 <= opA(3) XOR opB(3) XOR c2;
    g3 <= opA(3) AND opB(3);
    p3 <= opA(3) OR opB(3);
    c3 <= g3 OR (p3 AND c2);
   
    sum <= s3 & s2 & s1 & s0;
    carry_out <= c3;
   
end Behavioral;

 

0 Kudos
eilert
Teacher
Teacher
8,245 Views
Registered: ‎08-14-2007

Hi adrialex,

a post-route simulation always looks different compared to a behavioral simulation, because you see all the signal changes caused by delays.

 

And if your testbench is not prepared for that, it may totally fail. 

e.g.: if your inputs change at the active clock edge your simulator will take the data one clock too late in the best case. Or you will get a setup/hold violation warning.

So make sure, that all stimulis change a good time before the active clock edge, so the FFs recognize them as stable during setup/hold times.

 

For the synthesis warnings:

 line 50: One or more signals are missing in the process sensitivity list. To enable synthesis of FPGA/CPLD hardware, XST will assume that all necessary signals are present in the sensitivity list. Please note that the result of the synthesis may differ from the initial design specification. The missing signals are:
   <opA>, <opB>

 

Oops, you did it again... :-)

And this time it's important, because you are assigning these values in the asynchronous preset branch. This could lead to simulation misbehaviour.

 While you reset branch looks good, your Data loading sequence should better be synchronous. So copy the 'if en ' part into the 'if clock'event 'branch.

 

And the real nasty part is:

 

WARNING:Xst:737 - Found 4-bit latch for signal <op_shift1>.
WARNING:Xst:737 - Found 4-bit latch for signal <op_add2>.
WARNING:Xst:737 - Found 4-bit latch for signal <op_shift2>.
WARNING:Xst:737 - Found 4-bit latch for signal <tempA>.
WARNING:Xst:737 - Found 1-bit latch for signal <d>.

WARNING:Xst:737 - Found 5-bit latch for signal <nstate>.

Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.
 

Avoid latches!

Use else branches with each 'if'

Use when others in case construchts.

 Don't forget to assign all values that you are using in that area in each when condition.

 This can blow up your code unneccessarily, but there's a way to simplify it:

 

 --default assignments

  value1 <= '0';

  value2 <= '0';

  value3 <= '0';

  case sometimes is

    when 1 =>  value1 <= '1';

                       value3 <= '1';

    when 2 =>  value2 <= '1';

    when 3 =>  value3 <= '1';

    when others =>  value2 <= '1';

                               value1 <= '1';

  end case;

 

 This causes all unassigned values to stay at their default values and prevents latches.

 

 The warnings about the unused bits in the nstate signal can be ignored.

 They just tell you that you are using less bits of your state vector than available, so the unused bits are optimized away.

 

So, it's time for the next coding change iteration...

  Have a nice synthesis

    Eilert

mcgett
Xilinx Employee
Xilinx Employee
8,228 Views
Registered: ‎01-03-2008

Code that looks like this

 

changes : process(rst,clk,en,op_shift1,op_shift2)
    begin
        if rst = '1' then
            tempB <= "0000";
        elsif en = '1' then
            tempB <= opB;;
        else
            if clk'event and clk = '1' then

                tempB <= op_shift1;

           end if;

        end if;

end process

This won't synthesize into anything that works. I don't know of a technology that supports a register with an asynchronous data enable.  If you look at the synthesis report file I wouldn't be surprised to see notes/warnings about "combinatorial loops" and "latches".

 

The code should look like this.

changes : process(rst,clk)
    begin
        if rst = '1' then
            tempB <= "0000";
        elsif clk'event and clk = '1' then

                          if en = '1' then
               tempB <= opB;

            else

               tempB <= op_shift1;

           end if;

        end if;

end process;

Or preferably with a synchronous reset

changes : process(clk)
    begin
        if clk'event and clk = '1' then

           if rst = '1' then
               tempB <= "0000";

                       elsif en = '1' then
               tempB <= opB;

           else

               tempB <= op_shift1;

           end if;

        end if;

end process
 

 

------Have you tried typing your question into Google? If not you should before posting.
Too many results? Try adding site:www.xilinx.com
adrialex
Visitor
Visitor
8,203 Views
Registered: ‎08-05-2009

i've managed to fix my previous code and was able to synthesize it. my problem now is that i can't synthesize this code below. all the components included are synthesizable and i can't figure out how to make my post-route waveform the same as my behavioral waveform. pls help me with regards to this matter. thank you. pls tell me if you need the components included to be able to tell the problem.

 

 ----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date:    15:04:12 09/13/2009
-- Design Name:
-- Module Name:    datapath - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity datapath is
    Port ( clk : in  STD_LOGIC;
           rst : in  STD_LOGIC;
           inst : in  STD_LOGIC_VECTOR (1 downto 0);
           inst_fetch : out  STD_LOGIC;
           inst_done : out  STD_LOGIC;
           operandA : out  STD_LOGIC_VECTOR (7 downto 0);
           operandB : out  STD_LOGIC_VECTOR (7 downto 0);
           result : out  STD_LOGIC_VECTOR (7 downto 0));
end datapath;

architecture Behavioral of datapath is


     COMPONENT control
    PORT(
         clk : IN  std_logic;
         rst : IN  std_logic;
         done : IN  std_logic;
         inst : IN  std_logic_vector(1 downto 0);
         operation : OUT  std_logic_vector(3 downto 0);
         dest : OUT  std_logic_vector(3 downto 0);
         sourceA : OUT  std_logic_vector(3 downto 0);
         sourceB : OUT  std_logic_vector(3 downto 0);
         wr_en : OUT  std_logic;
         mult_en : OUT  std_logic;
         inst_fetch : OUT  std_logic;
         wr_data : OUT  std_logic_vector(7 downto 0)
        );
    END COMPONENT;
    
     COMPONENT regfile
    PORT(
         clk : IN  std_logic;
         rst : IN  std_logic;
         rdA : IN  std_logic_vector(3 downto 0);
         rdB : IN  std_logic_vector(3 downto 0);
         dest : IN  std_logic_vector(3 downto 0);
         wr_data : IN  std_logic_vector(7 downto 0);
         wr_en : IN  std_logic;
         operandA : OUT  std_logic_vector(7 downto 0);
         operandB : OUT  std_logic_vector(7 downto 0)
        );
    END COMPONENT;
    
     COMPONENT functions
    PORT(
         clk : IN  std_logic;
         rst : IN  std_logic;
         operation : IN  std_logic_vector(3 downto 0);
         sourceA : IN  std_logic_vector(7 downto 0);
         sourceB : IN  std_logic_vector(7 downto 0);
         en : IN  std_logic;
         result : OUT  std_logic_vector(7 downto 0);
         done : OUT  std_logic
        );
    END COMPONENT;
    
     --INPUTS
        SIGNAL wr_data_reg : STD_LOGIC_VECTOR(7 downto 0);
        SIGNAL wr_en_reg : STD_LOGIC;
        
     --OUTPUTS
        SIGNAL wr_en_ctrl,mult_en_ctrl : STD_LOGIC;
        SIGNAL op_ctrl,dest_ctrl,srcA_ctrl,srcB_ctrl : STD_LOGIC_VECTOR(3 downto 0);
        SIGNAL wr_data_ctrl : STD_LOGIC_VECTOR(7 downto 0);
        SIGNAL opA_reg, opB_reg : STD_LOGIC_VECTOR(7 downto 0);
        SIGNAL result_fcn : STD_LOGIC_VECTOR(7 downto 0);
        SIGNAL done_fcn : STD_LOGIC;
begin
    
    ctrl: control PORT MAP (
          clk => clk,
          rst => rst,
          done => done_fcn,
          inst => inst,
          operation => op_ctrl,
          dest => dest_ctrl,
          sourceA => srcA_ctrl,
          sourceB => srcB_ctrl,
          wr_en => wr_en_ctrl,
          mult_en => mult_en_ctrl,
          inst_fetch => inst_fetch,
          wr_data => wr_data_ctrl
   );
        
    reg: regfile PORT MAP (
          clk => clk,
          rst => rst,
          rdA => srcA_ctrl,
          rdB => srcB_ctrl,
          dest => dest_ctrl,
          wr_data => wr_data_reg,
          wr_en => wr_en_reg,
          operandA => opA_reg,
          operandB => opB_reg
   );
    
    fcn: functions PORT MAP (
          clk => clk,
          rst => rst,
          operation => op_ctrl,
          sourceA => opA_reg,
          sourceB => opB_reg,
          en => mult_en_ctrl,
          result => result_fcn,
          done => done_fcn
   );

    wr_reg : process(wr_en_ctrl,done_fcn)
    begin
        if done_fcn = '1' then
            if wr_en_ctrl = '1' then
                wr_en_reg <= wr_en_ctrl;
                wr_data_reg <= wr_data_ctrl;
            else
                wr_en_reg <= done_fcn;
                wr_data_reg <= result_fcn;
            end if;
        else
            wr_en_reg <= '0';
        end if;
    end process;
    
    fcn_done : process(done_fcn)
    begin
        inst_done <= done_fcn;
    end process;
    
    outputs : process(opA_reg,opB_reg,result_fcn)
    begin
        operandA <= opA_reg;
        operandB <= opB_reg;
        result <= result_fcn;
    end process;
    
end Behavioral;

Message Edited by adrialex on 09-19-2009 08:35 AM
Message Edited by adrialex on 09-19-2009 08:37 AM
0 Kudos
eilert
Teacher
Teacher
8,177 Views
Registered: ‎08-14-2007

 Hi adrialex,

the post route simulation will never exactly look like the behavioral simulation.

 

But besides the missing components, the testbench source is important to know.

Because many differences between simulations are caused by poorly programmed testbenches.

 

Have a nice simulation

  Eilert

0 Kudos
adrialex
Visitor
Visitor
8,178 Views
Registered: ‎08-05-2009

this is my testbench. please tell me if there's anything wrong with it. thank you

 

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.all;
USE ieee.numeric_std.ALL;
 
ENTITY datapath_test IS
END datapath_test;
 
ARCHITECTURE behavior OF datapath_test IS
     constant clk_period : time := 0.05 us;
    -- Component Declaration for the Unit Under Test (UUT)
 
    COMPONENT datapath
    PORT(
         clk : IN  std_logic;
         rst : IN  std_logic;
         inst : IN  std_logic_vector(1 downto 0);
         inst_fetch : OUT  std_logic;
         inst_done : OUT  std_logic;
         operandA : OUT  std_logic_vector(7 downto 0);
         operandB : OUT  std_logic_vector(7 downto 0);
         result : OUT  std_logic_vector(7 downto 0)
        );
    END COMPONENT;
   

   --Inputs
   signal clk : std_logic := '1';
   signal rst : std_logic := '0';
   signal inst : std_logic_vector(1 downto 0) := (others => '0');

     --Outputs
   signal inst_fetch : std_logic;
   signal inst_done : std_logic;
   signal operandA : std_logic_vector(7 downto 0);
   signal operandB : std_logic_vector(7 downto 0);
   signal result : std_logic_vector(7 downto 0);

 
BEGIN
 
    -- Instantiate the Unit Under Test (UUT)
   uut: datapath PORT MAP (
          clk => clk,
          rst => rst,
          inst => inst,
          inst_fetch => inst_fetch,
          inst_done => inst_done,
          operandA => operandA,
          operandB => operandB,
          result => result
        );

   PROCESS
    begin
        clk <= '1';
        wait for clk_period/2;
        clk <= '0';
        wait for clk_period/2;
    end process;

    tb : PROCESS
    BEGIN

        rst <= '1';
        inst <= "11";
        wait for clk_period *2;
        rst <= '0';
        wait for clk_period;
        inst <= "01";
        wait for clk_period;
        inst <= "00";
        wait for clk_period;
        inst <= "00";
        wait for clk_period;
        inst <= "00";
        wait for clk_period;
        inst <= "00";
        wait for clk_period;
        inst <= "11";
        wait for clk_period;
        inst <= "01";
       
        wait for clk_period*3;
       
        inst <= "11";
        wait for clk_period;
        wait for clk_period;
        inst <= "01";
        wait for clk_period;
        inst <= "00";
        wait for clk_period;
        inst <= "01";
        wait for clk_period;
        inst <= "00";
        wait for clk_period;
        inst <= "01";
        wait for clk_period;
        inst <= "11";
        wait for clk_period;
        inst <= "01";
       
        wait for clk_period*3;
       
        inst <= "00";
        wait for clk_period;
        wait for clk_period;
        inst <= "01";
        wait for clk_period;
        inst <= "00";
        wait for clk_period;
        inst <= "10";
        wait for clk_period;
        inst <= "00";
        wait for clk_period;
        inst <= "01";
        wait for clk_period;
        inst <= "00";
        wait for clk_period;
        inst <= "00";
       
        wait for clk_period*3;
       
        inst <= "00";
        wait for clk_period;
        wait for clk_period;
        inst <= "10";
        wait for clk_period;
        inst <= "00";
        wait for clk_period;
        inst <= "11";
        wait for clk_period;
        inst <= "00";
        wait for clk_period;
        inst <= "00";
        wait for clk_period;
        inst <= "00";
        wait for clk_period;
        inst <= "01";
       
        wait for clk_period*3;
       
        inst <= "00";
        wait for clk_period;
        wait for clk_period;
        inst <= "01";
        wait for clk_period;
        inst <= "01";
        wait for clk_period;
        inst <= "00";
        wait for clk_period;
        inst <= "00";
        wait for clk_period;
        inst <= "00";
        wait for clk_period;
        inst <= "00";
        wait for clk_period;
        inst <= "11";
       
        wait for clk_period*3;
       
        inst <= "01";
        wait for clk_period;
        wait for clk_period;
        inst <= "01";
        wait for clk_period;
        inst <= "01";
        wait for clk_period;
        inst <= "00";
        wait for clk_period;
        inst <= "00";
        wait for clk_period;
        inst <= "01";
        wait for clk_period;
        inst <= "00";
        wait for clk_period;
        inst <= "11";
       
        wait for clk_period*7;
       
        inst <= "10";
        wait for clk_period;
        wait for clk_period;
        inst <= "01";
        wait for clk_period;
        inst <= "01";
        wait for clk_period;
        inst <= "10";
        wait for clk_period;
        inst <= "01";
        wait for clk_period;
        inst <= "01";
        wait for clk_period;
        inst <= "00";
        wait for clk_period;
        inst <= "11";
       
        wait for clk_period*3;
       
        inst <= "10";
        wait for clk_period;
        wait for clk_period;
        inst <= "10";
        wait for clk_period;
        inst <= "01";
        wait for clk_period;
        inst <= "11";
        wait for clk_period;
        inst <= "01";
        wait for clk_period;
        inst <= "10";
        wait for clk_period;
        inst <= "00";
        wait for clk_period;
        inst <= "11";
       
        wait for clk_period*3;
       
        inst <= "11";
        wait for clk_period;
        wait for clk_period;
        inst <= "10";
        wait for clk_period;
        inst <= "01";
        wait for clk_period;
        inst <= "01";
        wait for clk_period;
        inst <= "01";
        wait for clk_period;
        inst <= "10";
        wait for clk_period;
        inst <= "00";
        wait for clk_period;
        inst <= "11";
       
        wait;
        -- Place stimulus here
    END PROCESS;

END;

0 Kudos
eilert
Teacher
Teacher
8,170 Views
Registered: ‎08-14-2007

Hi Adrialex,

as expected you are changing your input signals on the rising edge.

This causes setup/hold violations in the simulation.

A better approach would be to generate the stimuli with a synchronous assignment:

Either using if rising_edge(clk), which makes the data change one clock period after the assignment. (Pipeline behaviour as in real circuits)

or you can use the if falling_edge(clk) version, wich causes to change the data in the FFs at the next rising edge, and you can see very clearly in the waveform windoew how data propagates from your inputs to the FFs.

 

For a first test you can just add a non integer multiplier to your first wait-command.

So the data should have enough time to setup before the active clock edge.

 

 

       rst <= '1';
        inst <= "11";
        wait for clk_period *1.7;
        rst <= '0';

 

Using wait for with integer multiples of the clock period also causes other problems, even for the behavioral simulation.

You never know which assignment is simmulated first. The difference is only one or more delta cycles (which is zero time) but the simulation tool does care wether the clock changed before the signal or not.

 

Give it a try, and tell me how things went.

 

Have a nice simulation

  Eilert 

0 Kudos
adrialex
Visitor
Visitor
8,161 Views
Registered: ‎08-05-2009

Hi Eilert,

 

 I've managed to get some output from my post-route waveform thanks to your info but i get some X's (are they don't cares?) on my result output. Also at the 8th assertion of inst_done i get a wrong output for my operandA output. The only change i made was the wait for command after my rst assignment. I would post my other components so that you could also see if there are errors on my other codes.

 

Thank You

Message Edited by adrialex on 09-22-2009 05:19 AM
0 Kudos
adrialex
Visitor
Visitor
7,066 Views
Registered: ‎08-05-2009

FOR MY CONTROL COMPONENT

 

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity control is
    Port ( clk : in  STD_LOGIC;
           rst : in  STD_LOGIC;
              done : in STD_LOGIC;
           inst : in  STD_LOGIC_VECTOR (1 downto 0);
           operation : out  STD_LOGIC_VECTOR (3 downto 0);
           dest : out  STD_LOGIC_VECTOR (3 downto 0);
           sourceA : out  STD_LOGIC_VECTOR (3 downto 0);
           sourceB : out  STD_LOGIC_VECTOR (3 downto 0);
           wr_en : out  STD_LOGIC;
           mult_en : out  STD_LOGIC;
              inst_fetch : out STD_LOGIC;
           wr_data : out  STD_LOGIC_VECTOR (7 downto 0));
end control;

architecture Behavioral of control is
   
    SIGNAL cstate,nstate : STD_LOGIC_VECTOR(3 downto 0);
    SIGNAL temp : STD_LOGIC_VECTOR(15 downto 0);
   
begin
   
    changes : process(rst,clk)
    begin
        if rst = '1' then
            cstate <= "0000";
        else
            if clk'event and clk = '1' then
                if done = '1' then
                    cstate <= "0000";
                else
                    cstate <= nstate;
                end if;
            end if;
        end if;
    end process;
   
    instances : process(cstate,temp,inst)
    begin
        case cstate is
            when "0000" =>
                temp(15 downto 14) <= inst;
                operation <= "0000";
                sourceA <= "0000";    sourceB <= "0000";
                wr_en <= '0';            mult_en <= '0';
                inst_fetch <= '0';
                nstate <= "0001";
            when "0001" =>
                temp(13 downto 12) <= inst;
                inst_fetch <= '1';
                nstate <= "0010";
            when "0010" =>
                temp(11 downto 10) <= inst;
                inst_fetch <= '1';
                nstate <= "0011";
            when "0011" =>
                temp(9 downto 8) <= inst;
                inst_fetch <= '1';
                nstate <= "0100";
            when "0100" =>
                temp(7 downto 6) <= inst;
                inst_fetch <= '1';
                nstate <= "0101";
            when "0101" =>
                temp(5 downto 4) <= inst;
                inst_fetch <= '1';
                nstate <= "0110";
            when "0110" =>
                temp(3 downto 2) <= inst;
                inst_fetch <= '1';
                nstate <= "0111";
            when "0111" =>
                temp(1 downto 0) <= inst;
                inst_fetch <= '1';
                nstate <= "1000";
            when "1000" =>
                inst_fetch <= '0';
                if temp(15 downto 14) = "00" then
                    if temp(13 downto 12) = "01" then
                       
                        dest <= temp(11 downto 8);
                        sourceA <= temp(7 downto 4);
                        sourceB <= temp(3 downto 0);
                    else
                       
                        dest <= temp(11 downto 8);
                        sourceA <= temp(7 downto 4);
                        sourceB <= temp(3 downto 0);
                    end if;
                    nstate <= "1001";
                end if;
               
                if temp(15 downto 14) = "01" then
               
                    dest <= temp(13 downto 10);
                    sourceA <= temp(9 downto 6);
                    sourceB <= temp(5 downto 2);
                   
                    nstate <= "1001";
                end if;
               
                if temp(15 downto 14) = "10" then
                    if temp(13 downto 12) = "01" then
                       
                        dest <= temp(11 downto 8);
                        sourceA <= temp(7 downto 4);
                        sourceB <= "0000";
                    else
                       
                        dest <= temp(11 downto 8);
                        sourceA <= temp(7 downto 4);
                        sourceB <= "0000";
                    end if;
                    nstate <= "1001";
                end if;
               
                if temp(15 downto 14) = "11" then
                    if temp(13 downto 12) = "01" then
                        dest <= temp(11 downto 8);
                        wr_data <= temp(7 downto 0);
                        sourceA <= "0000";
                        sourceB <= "0000";
                    else
                        dest <= temp(11 downto 8);
                        sourceA <= "0000";
                        sourceB <= "0000";
                    end if;
                    nstate <= "1001";
                end if;
            when "1001" =>
                if temp(15 downto 14) = "00" then
                    if temp(13 downto 12) = "01" then
                        operation <= "0001";
                    else
                        operation <= "0010";
                    end if;
                end if;
                if temp(15 downto 14) = "01" then
                    operation <= "0100";
                    mult_en <= '1';
                end if;
                if temp(15 downto 14) = "10" then
                    if temp(13 downto 12) = "01" then
                        operation <= "1001";
                    else
                        operation <= "1010";
                    end if;
                end if;
                if temp(15 downto 14) = "11" then
                    if temp(13 downto 12) = "01" then
                        operation <= "1101";
                    else
                        operation <= "1110";
                    end if;
                end if;
                nstate <= "1010";
            when others =>
                if temp(15 downto 14) = "01" then
                    mult_en <= '0';
                elsif temp(15 downto 12) = "1101" then
                    wr_en <= '1';
                end if;
                nstate <= "1010";
        end case;
           
    end process;

end Behavioral;

0 Kudos
adrialex
Visitor
Visitor
7,065 Views
Registered: ‎08-05-2009

FOR MY REGFILE COMPONENT

 

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity regfile is
    Port ( clk : in  STD_LOGIC;
           rst : in  STD_LOGIC;
           rdA : in  STD_LOGIC_VECTOR (3 downto 0);
           rdB : in  STD_LOGIC_VECTOR (3 downto 0);
           dest : in  STD_LOGIC_VECTOR (3 downto 0);
           wr_data : in  STD_LOGIC_VECTOR (7 downto 0);
           wr_en : in  STD_LOGIC;
           operandA : out  STD_LOGIC_VECTOR (7 downto 0);
           operandB : out  STD_LOGIC_VECTOR (7 downto 0));
end regfile;

architecture Behavioral of regfile is

    --REGISTERS
    SIGNAL register00 : STD_LOGIC_VECTOR(7 downto 0);
    SIGNAL register01 : STD_LOGIC_VECTOR(7 downto 0);
    SIGNAL register02 : STD_LOGIC_VECTOR(7 downto 0);
    SIGNAL register03 : STD_LOGIC_VECTOR(7 downto 0);
    SIGNAL register04 : STD_LOGIC_VECTOR(7 downto 0);
    SIGNAL register05 : STD_LOGIC_VECTOR(7 downto 0);
    SIGNAL register06 : STD_LOGIC_VECTOR(7 downto 0);
    SIGNAL register07 : STD_LOGIC_VECTOR(7 downto 0);
    SIGNAL register08 : STD_LOGIC_VECTOR(7 downto 0);
    SIGNAL register09 : STD_LOGIC_VECTOR(7 downto 0);
    SIGNAL register10 : STD_LOGIC_VECTOR(7 downto 0);
    SIGNAL register11 : STD_LOGIC_VECTOR(7 downto 0);
    SIGNAL register12 : STD_LOGIC_VECTOR(7 downto 0);
    SIGNAL register13 : STD_LOGIC_VECTOR(7 downto 0);
    SIGNAL register14 : STD_LOGIC_VECTOR(7 downto 0);
    SIGNAL register15 : STD_LOGIC_VECTOR(7 downto 0);

begin

    process(clk,rst,rdA,rdB,dest,wr_en,wr_data)
    begin
        if clk'event and clk = '1' then
            if rst = '1' then
                register00 <= "00000000"; register01 <= "00000000"; register02 <= "00000000"; register03 <= "00000000";
                register04 <= "00000000"; register05 <= "00000000"; register06 <= "00000000"; register07 <= "00000000";
                register08 <= "00000000"; register09 <= "00000000"; register10 <= "00000000"; register11 <= "00000000";
                register12 <= "00000000"; register13 <= "00000000"; register14 <= "00000000"; register15 <= "00000000";
                operandA <= "00000000";
                operandB <= "00000000";
               
            elsif wr_en = '1' then
                case dest is
                    when "0000" =>
                        register00 <= wr_data;
                    when "0001" =>
                        register01 <= wr_data;
                    when "0010" =>
                        register02 <= wr_data;
                    when "0011" =>
                        register03 <= wr_data;
                    when "0100" =>
                        register04 <= wr_data;
                    when "0101" =>
                        register05 <= wr_data;
                    when "0110" =>
                        register06 <= wr_data;
                    when "0111" =>
                        register07 <= wr_data;
                    when "1000" =>
                        register08 <= wr_data;
                    when "1001" =>
                        register09 <= wr_data;
                    when "1010" =>
                        register10 <= wr_data;
                    when "1011" =>
                        register11 <= wr_data;
                    when "1100" =>
                        register12 <= wr_data;
                    when "1101" =>
                        register13 <= wr_data;
                    when "1110" =>
                        register14 <= wr_data;
                    when others =>
                        register15 <= wr_data;
                end case;
               
            else
                case rdA is
                    when "0000" =>
                        operandA <= register00;
                    when "0001" =>
                        operandA <= register01;
                    when "0010" =>
                        operandA <= register02;
                    when "0011" =>
                        operandA <= register03;
                    when "0100" =>
                        operandA <= register04;
                    when "0101" =>
                        operandA <= register05;
                    when "0110" =>
                        operandA <= register06;
                    when "0111" =>
                        operandA <= register07;
                    when "1000" =>
                        operandA <= register08;
                    when "1001" =>
                        operandA <= register09;
                    when "1010" =>
                        operandA <= register10;
                    when "1011" =>
                        operandA <= register11;
                    when "1100" =>
                        operandA <= register12;
                    when "1101" =>
                        operandA <= register13;
                    when "1110" =>
                        operandA <= register14;
                    when others =>
                        operandA <= register15;
                end case;
               
                case rdB is
                    when "0000" =>
                        operandB <= register00;
                    when "0001" =>
                        operandB <= register01;
                    when "0010" =>
                        operandB <= register02;
                    when "0011" =>
                        operandB <= register03;
                    when "0100" =>
                        operandB <= register04;
                    when "0101" =>
                        operandB <= register05;
                    when "0110" =>
                        operandB <= register06;
                    when "0111" =>
                        operandB <= register07;
                    when "1000" =>
                        operandB <= register08;
                    when "1001" =>
                        operandB <= register09;
                    when "1010" =>
                        operandB <= register10;
                    when "1011" =>
                        operandB <= register11;
                    when "1100" =>
                        operandB <= register12;
                    when "1101" =>
                        operandB <= register13;
                    when "1110" =>
                        operandB <= register14;
                    when others =>
                        operandB <= register15;
                end case;
            end if;
        end if;

    end process;
end Behavioral;

0 Kudos
adrialex
Visitor
Visitor
7,063 Views
Registered: ‎08-05-2009

FOR MY FUNCTION COMPONENT

 

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity functions is
    Port ( clk : in  STD_LOGIC;
           rst : in  STD_LOGIC;
           operation : in  STD_LOGIC_VECTOR (3 downto 0);
           sourceA : in  STD_LOGIC_VECTOR (7 downto 0);
           sourceB : in  STD_LOGIC_VECTOR (7 downto 0);
           en : in  STD_LOGIC;
              state : out STD_LOGIC_VECTOR (2 downto 0);
              oper_out : out STD_LOGIC_VECTOR (3 downto 0);
           result : out  STD_LOGIC_VECTOR (7 downto 0);
           done : out  STD_LOGIC);
end functions;

architecture Behavioral of functions is
   
    SIGNAL cstate, nstate : STD_LOGIC_VECTOR(2 downto 0);
    SIGNAL d : STD_LOGIC;
    SIGNAL temp : STD_LOGIC_VECTOR(3 downto 0);
    SIGNAL temp_prod : STD_LOGIC_VECTOR(7 downto 0);
   
    COMPONENT adder
    PORT(
         rst : IN  std_logic;
         operandA : IN  std_logic_vector(7 downto 0);
         operandB : IN  std_logic_vector(7 downto 0);
         carry_in : IN  std_logic;
         carry_out : OUT  std_logic;
         sum : OUT  std_logic_vector(7 downto 0)
        );
    END COMPONENT;
     
    COMPONENT multiplier
    PORT(
        clk : IN std_logic;
        rst : IN std_logic;
        en : IN std_logic;
        opA : IN std_logic_vector(3 downto 0);
        opB : IN std_logic_vector(3 downto 0);         
        res : OUT std_logic_vector(7 downto 0);
        done : OUT std_logic
        );
     END COMPONENT;
   
    COMPONENT inverter
    PORT(
         rst : IN  std_logic;
         operand : IN  std_logic_vector(7 downto 0);
         result : OUT  std_logic_vector(7 downto 0)
        );
    END COMPONENT;
     
     COMPONENT compliment
    PORT(
         rst : IN  std_logic;
         operand : IN  std_logic_vector(7 downto 0);
         result : OUT  std_logic_vector(7 downto 0)
        );
    END COMPONENT;
   
    --INPUTS
        SIGNAL op_add1,op_add2 : STD_LOGIC_VECTOR(7 downto 0);
        SIGNAL op_inv : STD_LOGIC_VECTOR(7 downto 0);
        SIGNAL op_mult1,op_mult2 : STD_LOGIC_VECTOR(3 downto 0);
        SIGNAL op_comp : STD_LOGIC_VECTOR(7 downto 0);
       
    --OUTPUTS
        SIGNAL sum_add : STD_LOGIC_VECTOR(7 downto 0);
        SIGNAL res_mult : STD_LOGIC_VECTOR(7 downto 0);
        SIGNAL res_inv : STD_LOGIC_VECTOR(7 downto 0);
        SIGNAL res_comp : STD_LOGIC_VECTOR(7 downto 0);
        SIGNAL carry_out_add : STD_LOGIC;
        SIGNAL done_mult : STD_LOGIC;
       
begin
    add: adder PORT MAP (
          rst => rst,
          operandA => op_add1,
          operandB => op_add2,
          carry_in => '0',
          carry_out => carry_out_add,
          sum => sum_add
   );
   
    multiply: multiplier PORT MAP(
        clk => clk,
        rst => rst,
        en => en,
        opA => op_mult1,
        opB => op_mult2,
        res => res_mult,
        done => done_mult
    );
   
    invert: inverter PORT MAP (
          rst => rst,
          operand => op_inv,
          result => res_inv
   );
   
    complimenter: compliment PORT MAP (
          rst => rst,
          operand => op_comp,
          result => res_comp
   );
   
    changes : process(rst,clk,nstate)
    begin
        if rst = '1' then
            cstate <= "000";
        else
            if clk'event and clk = '1' then
                cstate <= nstate;
                state <= nstate;
            end if;
        end if;
    end process;
   
    states : process(cstate,temp,operation,sourceA,sourceB,sum_add,res_inv,res_mult,done_mult,temp_prod)
    begin
        case cstate is
            when "000" =>
                temp <= operation;
                if operation = "0000" then
                    nstate <= "000";
                elsif operation = "0100" then
                    op_mult1 <= sourceA(3 downto 0);
                    op_mult2 <= sourceB(3 downto 0);
                    nstate <= "001";
                elsif operation = "0010" then
                    op_comp <= sourceB;
                    nstate <= "001";
                elsif operation = "1001" then
                    op_inv <= sourceA;
                    nstate <= "001";
                else
                    nstate <= "001";
                end if;
            when "001" =>
                oper_out <= temp;
                if temp = "0001" then
                    op_add1 <= sourceA;
                    op_add2 <= sourceB;
                    result <= sum_add;
                    done <= '1';
                    nstate <= "010";
                elsif temp = "0010" then
                    op_add1 <= sourceA;
                    op_add2 <= res_comp;
                    result <= sum_add;
                    done <= '1';
                    nstate <= "010";
                elsif temp = "0100" then
                    nstate <= "010";
                elsif temp = "1001" then
                    result <= res_inv;
                    done <= '1';
                    nstate <= "010";
                elsif temp = "1010" then
                    result <= sourceA;
                    done <= '1';
                    nstate <= "010";
                elsif temp = "1101" then
                    result <= "00000000";
                    done <= '1';
                    nstate <= "010";
                elsif temp = "1110" then
                    result <= "00000000";
                    done <= '1';
                    nstate <= "010";
                else
                    nstate <= "000";
                end if;
            when "010" =>
                if temp = "0001" then
                    done <= '0';
                    nstate <= "000";
                elsif temp = "0010" then
                    done <= '0';
                    nstate <= "000";
                elsif temp = "0100" then
                    nstate <= "011";
                elsif temp = "1001" then
                    done <= '0';
                    nstate <= "000";
                elsif temp = "1010" then
                    done <= '0';
                    nstate <= "000";
                elsif temp = "1101" then
                    done <= '0';
                    nstate <= "000";
                elsif temp = "1110" then
                    result <= "00000000";
                    done <= '0';
                    nstate <= "000";
                else
                    done <= '0';
                    nstate <= "000";
                end if;
            when "011" =>
                if temp = "0100" then
                    nstate <= "100";
                else
                    nstate <= "000";
                    done <= '0';
                end if;
            when "100" =>
                if temp = "0100" then
                    nstate <= "101";
                else
                    nstate <= "000";
                    done <= '0';
                end if;
            when "101" =>
                if temp = "0100" then
                    result <= res_mult;
                    temp_prod <= res_mult;
                    done <= '1';
                    nstate <= "110";
                else
                    done <= '0';
                    nstate <= "000";
                end if;
            when "110" =>
                if temp = "0100" then
                    result <= temp_prod;
                    done <= '0';
                    nstate <= "000";
                else
                    done <= '0';
                    nstate <= "000";
                end if;
            when others =>   
                done <= '0';
                nstate <= "000";
        end case;
   
    end process;

end Behavioral;

0 Kudos
adrialex
Visitor
Visitor
7,062 Views
Registered: ‎08-05-2009

FOR MY ADDER COMPONENT

 

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity adder is
    Port ( rst : in  STD_LOGIC;
           operandA : in  STD_LOGIC_VECTOR (7 downto 0);
           operandB : in  STD_LOGIC_VECTOR (7 downto 0);
           carry_in : in  STD_LOGIC;
           carry_out : out  STD_LOGIC;
           sum : out  STD_LOGIC_VECTOR (7 downto 0));
end adder;

architecture Behavioral of adder is
    COMPONENT cla_adder
    PORT(
         opA : IN  std_logic_vector(3 downto 0);
         opB : IN  std_logic_vector(3 downto 0);
         carry_in : IN  std_logic;
         sum : OUT  std_logic_vector(3 downto 0);
         carry_out : OUT  std_logic
        );
    END COMPONENT;
     
    --INPUTS
    SIGNAL oper_add1 : STD_LOGIC_VECTOR(3 downto 0);
    SIGNAL oper_add2 : STD_LOGIC_VECTOR(3 downto 0);
    SIGNAL oper_add3 : STD_LOGIC_VECTOR(3 downto 0);
    SIGNAL oper_add4 : STD_LOGIC_VECTOR(3 downto 0);
   
    --OUTPUTS
    SIGNAL sum_add1 : STD_LOGIC_VECTOR(3 downto 0);
    SIGNAL sum_add2 : STD_LOGIC_VECTOR(3 downto 0);
    SIGNAL carry_out_add1 : STD_LOGIC;
    SIGNAL carry_out_add2 : STD_LOGIC;
   
begin
    lower: cla_adder PORT MAP (
          opA => oper_add1,
          opB => oper_add2,
          carry_in => '0',
          sum => sum_add1,
          carry_out => carry_out_add1
        );

    upper: cla_adder PORT MAP (
          opA => oper_add3,
          opB => oper_add4,
          carry_in => carry_out_add1,
          sum => sum_add2,
          carry_out => carry_out_add2
        );

    process(rst,sum_add1,sum_add2,carry_out_add2,operandA,operandB)
    begin
        if rst = '1' then
            oper_add1 <= "0000"; oper_add2 <= "0000"; oper_add3 <= "0000"; oper_add4 <= "0000";
            sum <= "00000000";
            carry_out <= '0';
        else
                oper_add1 <= operandA(3 downto 0);
                oper_add2 <= operandB(3 downto 0);
                oper_add3 <= operandA(7 downto 4);
                oper_add4 <= operandB(7 downto 4);
                sum <= sum_add2 & sum_add1;
                carry_out <= carry_out_add2;
        end if;
       
    end process;

end Behavioral;

0 Kudos
adrialex
Visitor
Visitor
7,061 Views
Registered: ‎08-05-2009

FOR MY CLA_ADDER COMPONENT

 

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity cla_adder is
    Port ( opA : in  STD_LOGIC_VECTOR (3 downto 0);
           opB : in  STD_LOGIC_VECTOR (3 downto 0);
           carry_in : in  STD_LOGIC;
           sum : out  STD_LOGIC_VECTOR (3 downto 0);
           carry_out : out  STD_LOGIC);
end cla_adder;

architecture Behavioral of cla_adder is
    SIGNAL s0,s1,s2,s3 : STD_LOGIC;
    SIGNAL g0,g1,g2,g3 : STD_LOGIC;
    SIGNAL p0,p1,p2,p3 : STD_LOGIC;
    SIGNAL c0,c1,c2,c3 : STD_LOGIC;
begin
    s0 <= opA(0) XOR opB(0) XOR carry_in;
    g0 <= opA(0) AND opB(0);
    p0 <= opA(0) OR opB(0);
    c0 <= g0 OR (p0 AND carry_in);
   
    s1 <= opA(1) XOR opB(1) XOR c0;
    g1 <= opA(1) AND opB(1);
    p1 <= opA(1) OR opB(1);
    c1 <= g1 OR (p1 AND c0);
   
    s2 <= opA(2) XOR opB(2) XOR c1;
    g2 <= opA(2) AND opB(2);
    p2 <= opA(2) OR opB(2);
    c2 <= g2 OR (p2 AND c1);
   
    s3 <= opA(3) XOR opB(3) XOR c2;
    g3 <= opA(3) AND opB(3);
    p3 <= opA(3) OR opB(3);
    c3 <= g3 OR (p3 AND c2);
   
    sum <= s3 & s2 & s1 & s0;
    carry_out <= c3;
   
end Behavioral;

0 Kudos
adrialex
Visitor
Visitor
7,060 Views
Registered: ‎08-05-2009

FOR MY MULTIPLIER COMPONENT

 

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity multiplier is
    Port ( clk : in  STD_LOGIC;
           rst : in  STD_LOGIC;
           en : in  STD_LOGIC;
           opA : in  STD_LOGIC_VECTOR (3 downto 0);
           opB : in  STD_LOGIC_VECTOR (3 downto 0);
           res : out  STD_LOGIC_VECTOR (7 downto 0);
           done : out  STD_LOGIC);
end multiplier;

architecture Behavioral of multiplier is

    SIGNAL tempA,tempB : STD_LOGIC_VECTOR(3 downto 0);
    SIGNAL cstate,nstate : STD_LOGIC_VECTOR(2 downto 0);
   
    COMPONENT cla_adder
    PORT ( opA : IN  std_logic_vector (3 downto 0);
           opB : IN  std_logic_vector (3 downto 0);
           carry_in : IN  STD_LOGIC;
           sum : OUT  std_logic_vector (3 downto 0);
           carry_out : OUT  STD_LOGIC
            );
    END COMPONENT;
   
    --Inputs
    SIGNAL op_add1 :  std_logic_vector(3 downto 0);
    SIGNAL op_add2 :  std_logic_vector(3 downto 0);
    SIGNAL op_shift1 :  std_logic_vector(3 downto 0);
    SIGNAL op_shift2 :  std_logic_vector(3 downto 0);
   
    --Outputs
    SIGNAL sum_add :  std_logic_vector(3 downto 0);
    SIGNAL carry_out_add :  std_logic;
    SIGNAL d : std_logic;
   
begin
    adding: cla_adder PORT MAP(
        opA => op_add1,
        opB => op_add2,
        carry_in => '0',
        sum => sum_add,
        carry_out => carry_out_add
    );
   
    changes : process(rst,clk,en,op_shift1,op_shift2)
    begin
        if rst = '1' then
            cstate <= "000";
            res <= "00000000";
            done <= '0';
            op_add1 <= "0000";
            tempA <= "0000";
            tempB <= "0000";
        elsif en = '1' then
            tempA <= opA;
            tempB <= opB;
            cstate <= "000";
            op_add1 <= "0000";
            done <= '0';
        else
            if clk'event and clk = '1' then
                cstate <= nstate;
                op_add1 <= op_shift2;
                tempB <= op_shift1;
                if d = '1' then
                    res <= op_shift2 & op_shift1;
                    done <= '1';
                else
                    done <= '0';
                end if;
            end if;
        end if;
    end process;

    instances : process(cstate,en,rst,tempA,tempB,sum_add,carry_out_add,op_shift1,op_shift2)
    begin
        if en = '0' and rst = '0' then
        case cstate is
            when "000" =>
                if tempB(0) = '1' then
                    op_add2 <= tempA;
                    op_shift2 <= carry_out_add & sum_add(3 downto 1);
                    op_shift1 <= sum_add(0) & tempB(3 downto 1);
                    nstate <= "001";
                else
                    op_add2 <= "0000";
                    op_shift2 <= carry_out_add & sum_add(3 downto 1);
                    op_shift1 <= sum_add(0) & tempB(3 downto 1);
                    nstate <= "001";
                end if;
            when "001" =>
                if tempB(0) = '1' then
                    op_add2 <= tempA;
                    op_shift2 <= carry_out_add & sum_add(3 downto 1);
                    op_shift1 <= sum_add(0) & tempB(3 downto 1);
                    nstate <= "010";
                else
                    op_add2 <= "0000";
                    op_shift2 <= carry_out_add & sum_add(3 downto 1);
                    op_shift1 <= sum_add(0) & tempB(3 downto 1);
                    nstate <= "010";
                end if;
            when "010" =>
                if tempB(0) = '1' then
                    op_add2 <= tempA;
                    op_shift2 <= carry_out_add & sum_add(3 downto 1);
                    op_shift1 <= sum_add(0) & tempB(3 downto 1);
                    nstate <= "011";
                else
                    op_add2 <= "0000";
                    op_shift2 <= carry_out_add & sum_add(3 downto 1);
                    op_shift1 <= sum_add(0) & tempB(3 downto 1);
                    nstate <= "011";
                end if;
            when "011" =>
                if tempB(0) = '1' then
                    op_add2 <= tempA;
                    op_shift2 <= carry_out_add & sum_add(3 downto 1);
                    op_shift1 <= sum_add(0) & tempB(3 downto 1);
                    d <= '1';
                    nstate <= "100";
                else
                    op_add2 <= "0000";
                    op_shift2 <= carry_out_add & sum_add(3 downto 1);
                    op_shift1 <= sum_add(0) & tempB(3 downto 1);
                    nstate <= "100";
                    d <= '1';
                end if;
            when others =>
                    d <= '0';
            end case;
        end if;
    end process;

end Behavioral;

 

0 Kudos
adrialex
Visitor
Visitor
7,059 Views
Registered: ‎08-05-2009

FOR MY INVERTER COMPONENT

 

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity inverter is
    Port ( rst : in  STD_LOGIC;
           operand : in  STD_LOGIC_VECTOR (7 downto 0);
           result : out  STD_LOGIC_VECTOR (7 downto 0));
end inverter;

architecture Behavioral of inverter is
    SIGNAL temp : std_logic_vector (7 downto 0);
   
begin
    process (rst,temp,operand)
    begin
        if rst = '1' then
            result <= "00000000";
            temp <= "00000000";

        elsif operand = "00000000" then
            result <= "00000000";
       
        else
            if operand(7) = '1' then
                temp(7) <= '0';
            else
                temp(7) <= '1';
            end if;
           
            if operand(6) = '1' then
                temp(6) <= '0';
            else
                temp(6) <= '1';
            end if;
           
            if operand(5) = '1' then
                temp(5) <= '0';
            else
                temp(5) <= '1';
            end if;
           
            if operand(4) = '1' then
                temp(4) <= '0';
            else
                temp(4) <= '1';
            end if;
           
            if operand(3) = '1' then
                temp(3) <= '0';
            else
                temp(3) <= '1';
            end if;
           
            if operand(2) = '1' then
                temp(2) <= '0';
            else
                temp(2) <= '1';
            end if;
           
            if operand(1) = '1' then
                temp(1) <= '0';
            else
                temp(1) <= '1';
            end if;
           
            if operand(0) = '1' then
                temp(0) <= '0';
            else
                temp(0) <= '1';
            end if;
                result <= temp;
        end if;
           
    end process;

end Behavioral;

 

0 Kudos
adrialex
Visitor
Visitor
7,060 Views
Registered: ‎08-05-2009

FOR MY COMPLIMENTER COMPONENT

 

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity compliment is
    Port ( rst : in  STD_LOGIC;
           operand : in  STD_LOGIC_VECTOR (7 downto 0);
           result : out  STD_LOGIC_VECTOR (7 downto 0));
end compliment;

architecture Behavioral of compliment is
    SIGNAL temp : std_logic_vector (7 downto 0);
   
    COMPONENT adder
    PORT(
         rst : IN  std_logic;
         operandA : IN  std_logic_vector(7 downto 0);
         operandB : IN  std_logic_vector(7 downto 0);
         carry_in : IN  std_logic;
         carry_out : OUT  std_logic;
         sum : OUT  std_logic_vector(7 downto 0)
        );
    END COMPONENT;
   
    --INPUTS
        SIGNAL oper_add : STD_LOGIC_VECTOR(7 downto 0);
       
    --OUTPUTS
        SIGNAL sum_add : STD_LOGIC_VECTOR(7 downto 0);
        SIGNAL carry_out_add : STD_LOGIC;
   
begin

    adding: adder PORT MAP (
          rst => rst,
          operandA => oper_add,
          operandB => "00000001",
          carry_in => '0',
          carry_out => carry_out_add,
          sum => sum_add
   );
   
   
    process (rst,temp,sum_add,operand)
    begin
        if rst = '1' then
            result <= "00000000";
            temp <= "00000000";
           
        elsif operand = "00000000" then
            result <= "00000000";
       
        else
            if operand(7) = '1' then
                temp(7) <= '0';
            else
                temp(7) <= '1';
            end if;
           
            if operand(6) = '1' then
                temp(6) <= '0';
            else
                temp(6) <= '1';
            end if;
       
            if operand(5) = '1' then
                temp(5) <= '0';
            else
                temp(5) <= '1';
            end if;
           
            if operand(4) = '1' then
                temp(4) <= '0';
            else
                temp(4) <= '1';
            end if;
           
            if operand(3) = '1' then
                temp(3) <= '0';
            else
                temp(3) <= '1';
            end if;
           
            if operand(2) = '1' then
                temp(2) <= '0';
            else
                temp(2) <= '1';
            end if;
           
            if operand(1) = '1' then
                temp(1) <= '0';
            else
                temp(1) <= '1';
            end if;
           
            if operand(0) = '1' then
                temp(0) <= '0';
            else
                temp(0) <= '1';
            end if;
                oper_add <= temp;
                result <= sum_add;
        end if;
           
   
    end process;
   
end Behavioral;

0 Kudos
eilert
Teacher
Teacher
7,027 Views
Registered: ‎08-14-2007

Hi Adrialex,

you still have some processes with incomplete sensitivity lists.

Look at the synthesis report and make the corrections. 

Your behavioral simulation will look much better then (eg. writing to register02 works then).

 

Still you have a lot of latches.

And what's this fancy inverter with all the if's for each bit?

 result <= not  operand;

that's all you need in the else branch.

So you can get rid of the temp signal, which had a missing assignment in the elsif branch annyway. (caused latches)

 

 

While the behavioral simulation actually seems to do something, the post route simulation is a mess.

After reset is released ('0') one adress multiplexing signal wents to 'X' and  causes the circuit to fail.

'X' is not don't care. It's a invalid result. With std logic the results of a logical operation are resolved uing a table.

There are tables for each logic function in the std_logic libraries.

e.g. for and 1 and 1 resolves to 1

                   0 and 1 resolves to 0

                   1 and U resolves to X    <- here an undefined input causes the and gate to generate a X-output

                   0 and U resolves to 0    <- here the output is '0' because it's always so when one input is '0'

                   etc...

 

Furthermore 'X'es can be generated as a result of a timing violation by the VITAL-libraries.

I have changed the wait before the reset release from clk_period*2 to clk_period*1.7.

Now the simulation does something useful inst_done comes for the first time.

But it's just active for 5 ns, and then it goes into 'X'-Hell.

Before that it goes '0' for some ps. This is either a pure combinatorical glitch, or one of your latches just begged for your personal attention. ;-)

 

 I tried to repair something using the proposed default scheme.

 

    instances : process(cstate,temp,inst)
    begin
         -- defaults cause wrong behavior
         --dest    <= (others => '0'); -- default value --eb
          --wr_data <= (others => '0'); -- default value --eb
        case cstate is
            when "0000" =>

 

 But somehow the rest of your code in this process does not fit to it. the assignments vanish too fast, and so the circuit does nothing.

 This needs proper rework. Maybe it would help  to add some registers for dest and wr_data, to keep the values. (Other things may need fixing too!)

 

Have a nice simulation

  Eilert 

 

0 Kudos