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.