Forum: FPGA, VHDL & Verilog 3x3 Determinant Calculation state problem

von Berk T. (canonind)

Rate this post
0 useful
not useful
I have designed a 3x3 determinant calculation chip. I have 5 states. 
However, simulation stops due to fatal error in the 4th state. My code 
is below:



entity determinant3x3 is
port(clk,reset:in std_logic;
     a11,a12,a13,a21,a22,a23,a31,a32,a33:in std_logic_vector(7 downto 
     determinant:out std_logic_vector(24 downto 0);
     done:out std_logic);
end determinant3x3;

architecture Structure of determinant3x3 is
--Intermediate signal declarations
signal detM11_res:std_logic_vector(15 downto 0);
signal detM12_res:std_logic_vector(15 downto 0);
signal detM13_res:std_logic_vector(15 downto 0);
signal SubResult_res:std_logic_vector(24 downto 0);
signal temp:std_logic_vector(24 downto 0);

--State declaration
type state_type is (Reset_state,detM11,detM12,detM13,SubResult,Result);
signal state: state_type;

--Control Path
control_path:process(clk,reset)--clocked process
    if reset = '1' then
        state <= Reset_state;
    elsif clk'event and clk = '1' then
        case state is
            when Reset_state =>
                state <= detM11;
            when detM11=>
                state <= detM12;
            when detM12=>
                state <= detM13;
            when detM13=>
                state <= SubResult;
            when SubResult=>
                state <= Result;
            when Result=>
                state <= detM11;
        end case;
    end if;
end process control_path;

--Data Path
data_path:process(state)--combinatorial process

--these are declared as variables, because these have to be assigned 
after the multiplications are performed
--so it has to be a blocking assignment for them. If these were defined 
as signals, it would be a non-blocking
--assignment and we would get the detM11_sub1's and detM11sub2's 
previous results, which we don't want.
variable detM11_sub1:std_logic_vector(15 downto 0);
variable detM11_sub2:std_logic_vector(15 downto 0);
variable detM12_sub1:std_logic_vector(15 downto 0);
variable detM12_sub2:std_logic_vector(15 downto 0);
variable detM13_sub1:std_logic_vector(15 downto 0);
variable detM13_sub2:std_logic_vector(15 downto 0);
variable SubResult_sub1:std_logic_vector(24 downto 0);
variable SubResult_sub2:std_logic_vector(24 downto 0);
variable Result_sub1:std_logic_vector(24 downto 0);

    case state is
        when Reset_state=>
            done <= '0';
        when detM11=>
            detM11_sub1 := a22*a33;
            detM11_sub2 := a23*a32;
            detM11_res <= detM11_sub1-detM11_sub2;
        when detM12=>
            detM12_sub1 := a21*a33;
            detM12_sub2 := a23*a31;
            detM12_res <= detM12_sub1-detM12_sub2;
        when detM13=>
            detM13_sub1 := a21*a32;
            detM13_sub2 := a22*a31;
            detM13_res <= detM13_sub1- detM13_sub2;
        when SubResult=>
            SubResult_sub1 := a11*detM11_res;
    --        SubResult_sub2 := a12*detM12_res;
            SubResult_res <= SubResult_sub1 - SubResult_sub2;
        when Result=>
    --        Result_sub1 := a13*detM13_res;
            temp <=  Result_sub1 + SubResult_res;
            done <= '1';
    end case;
determinant <= temp;
end process data_path;

end Structure;
Here, on the state "SubResult", the first line causes the error. But I 
don't understand why? Can't we assign signals to variables?

Thank you

von engineer (Guest)

Rate this post
0 useful
not useful
why do you use a fsm to do that?

especially determinant calculations work with much parital redundancy in 
terms of the use luts

you better do that in one clock

von Berk T. (canonind)

Rate this post
0 useful
not useful
Because I am limited to 2 multipliers and 1 adder/subtractor unit. But 
do you have any suggestions about the problem?

von Duke Scarring (Guest)

Rate this post
0 useful
not useful
at first:
Avoid this. You get unreliable code because the nice mix of 
std_logic_vector and unsigend. Use numeric_std instead and use proper 
types and type castings.

at second:
> simulation stops due to fatal error in the 4th state
No very specific error message. Which simulator? Which version?

at third:
Can you deliver at testbench? That will help others to reconstruct your 

at last (not least):
Is it necessary to mix up variables and signals that way? As beginner 
it's better to avoid variables.


von Berk T. (canonind)

Rate this post
0 useful
not useful
Ok. The testbench I used is this one:


entity tb is
end tb;

architecture Structure of tb is
--Component instantiation
component determinant3x3 port(clk,reset:in std_logic;
std_logic_vector(7 downto 0);
                determinant:out std_logic_vector(24 downto 0);
                done:out std_logic);
end component;

--Declare test signals
signal tb_clk:std_logic:='0';
signal tb_reset:std_logic:='1';
signal tb_a11,
     tb_a33:std_logic_vector(7 downto 0);
signal tb_determinant:std_logic_vector(24 downto 0);
signal tb_done:std_logic;

--Assign values to test signals
tb_reset <= '0' after 5 ns;
tb_clk <= not(tb_clk) after 10 ns;
tb_a11 <= "00001111";
tb_a12 <= "00001100";
tb_a13 <= "01001000";
tb_a21 <= "01001101";
tb_a22 <= "01000010";
tb_a23 <= "00000000";
tb_a31 <= "00001001";
tb_a32 <= "01001101";
tb_a33 <= "00001011";

--Connect component
DUT:determinant3x3 port map(tb_clk,tb_reset,
end Structure;

The simulator is Modelsim PE Student Edition 10.0c

And it hangs when it enters the "SubResult" state due to this line:
"SubResult_sub1 := a11*detM11_res;"

I don't understand what's wrong with it? Can you help me out?

von Lothar M. (lkmiller) (Moderator)

Rate this post
0 useful
not useful
> signal detM11_res:std_logic_vector(15 downto 0);
= 16 bits
> a11 : in std_logic_vector(7 downto 0);
= 8 bits
> variable SubResult_sub1:std_logic_vector(24 downto 0);
= 25 bits
>  SubResult_sub1 := a11*detM11_res;
16 bits * 8 bits = 24 bits

Thats the width calculated by the "*" operator in std_logic_unsigned:
        variable result  : STD_LOGIC_VECTOR ((L'length+R'length-1) downto 0);
        result  := UNSIGNED(L) * UNSIGNED(R);
        return   std_logic_vector(result);
(L'length+R'length-1) = 16+8-1 =23
So try:
variable SubResult_sub1:std_logic_vector(23 downto 0);

I recommende the use of
use IEEE.numeric_std.all;
instead of
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;

von Berk T. (canonind)

Rate this post
0 useful
not useful
Thank you. That was the problem

von Duke Scarring (Guest)

Rate this post
0 useful
not useful
The Modelsim compiler give me the following warning:
$ vlib work
$ vcom -source det.vhd
Model Technology ModelSim PE vcom 10.1 Beta 2 Compiler 2011.10 Oct  1 2011
-- Loading package STANDARD
-- Loading package TEXTIO
-- Loading package std_logic_1164
-- Loading package std_logic_arith
-- Loading package STD_LOGIC_UNSIGNED
-- Compiling entity determinant3x3
-- Compiling architecture Structure of determinant3x3
###### det.vhd(84):             SubResult_sub1 := a11*detM11_res;
** Warning: [14] det.vhd(84): (vcom-1272) Length of expected is 25; length of actual is 24.
This is one of the warnings that I would not ignore :-)


von Berk T. (canonind)

Rate this post
0 useful
not useful
Yes, now I corrected it as you said. Thank you again. It was very 


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.