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: ---------------------------------------------------- LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; entity determinant3x3 is port(clk,reset:in std_logic; a11,a12,a13,a21,a22,a23,a31,a32,a33:in std_logic_vector(7 downto 0); 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; begin --Control Path control_path:process(clk,reset)--clocked process begin 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); begin 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
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
Because I am limited to 2 multipliers and 1 adder/subtractor unit. But do you have any suggestions about the problem?
at first: > USE IEEE.STD_LOGIC_UNSIGNED.ALL; 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 stuff. at last (not least): Is it necessary to mix up variables and signals that way? As beginner it's better to avoid variables. Duke
Ok. The testbench I used is this one: -------------------------------------------------- LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; entity tb is end tb; architecture Structure of tb is --Component instantiation component determinant3x3 port(clk,reset:in std_logic; a11,a12,a13,a21,a22,a23,a31,a32,a33:in 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_a12, tb_a13, tb_a21, tb_a22, tb_a23, tb_a31, tb_a32, tb_a33:std_logic_vector(7 downto 0); signal tb_determinant:std_logic_vector(24 downto 0); signal tb_done:std_logic; begin --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, tb_a11,tb_a12,tb_a13,tb_a21,tb_a22,tb_a23,tb_a31,tb_a32,tb_a33, tb_determinant,tb_done); 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?
> 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 But > SubResult_sub1 := a11*detM11_res; 16 bits * 8 bits = 24 bits Thats the width calculated by the "*" operator in std_logic_unsigned:
1 | function "*"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is |
2 | variable result : STD_LOGIC_VECTOR ((L'length+R'length-1) downto 0); |
3 | begin
|
4 | result := UNSIGNED(L) * UNSIGNED(R); |
5 | return std_logic_vector(result); |
6 | end; |
(L'length+R'length-1) = 16+8-1 =23 So try: variable SubResult_sub1:std_logic_vector(23 downto 0); BTW: I recommende the use of use IEEE.numeric_std.all; instead of use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all;
The Modelsim compiler give me the following warning:
1 | $ vlib work |
2 | $ vcom -source det.vhd |
3 | Model Technology ModelSim PE vcom 10.1 Beta 2 Compiler 2011.10 Oct 1 2011 |
4 | -- Loading package STANDARD |
5 | -- Loading package TEXTIO |
6 | -- Loading package std_logic_1164 |
7 | -- Loading package std_logic_arith |
8 | -- Loading package STD_LOGIC_UNSIGNED |
9 | -- Compiling entity determinant3x3 |
10 | -- Compiling architecture Structure of determinant3x3 |
11 | ###### det.vhd(84): SubResult_sub1 := a11*detM11_res; |
12 | ** 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 :-) Duke
Yes, now I corrected it as you said. Thank you again. It was very helpful.
Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
Log in with Google account
No account? Register here.