[英]Ise simulation VHDL
I would like to ask the following. 我想问以下问题。 I am working on an FPGA Tetris design.
我正在从事FPGA Tetris设计。 My code language is VHDL in ISE Environment in windows 7.
我的代码语言是Windows 7中ISE环境中的VHDL。
While I progress my work I ofter check my work with isim simulation. 在进行工作时,我经常通过isim模拟检查工作。 As the design is getting big isim stops working and closes.
随着设计变大,isim停止工作并关闭。 Basically the module causing this crash is a big fsm.
基本上,导致崩溃的模块是很大的fsm。 When I comment some states of the fsm ISIM is working fine again.
当我评论fsm的某些状态时,ISIM再次正常运行。
It doesn't matter which states I will comment. 我要评论哪个状态都没关系。 I can check the fsm working in parts.
我可以检查部分工作的fsm。 But I can not test it as a whole.
但是我无法整体测试。 Is it possible that this is not code error and it is just ISIM?
这可能不是代码错误,而只是ISIM吗?
Thanks 谢谢
How to split a complex FSM into parts? 如何将复杂的FSM分成几部分?
Here are some example lines to illustrate a simple call/return handshaking protocol between a main FSM and two function FSMs 这是一些示例行,用于说明主FSM和两个功能FSM之间的简单呼叫/返回握手协议
process(Clock)
begin
if (Reset = '1') then
MainFSM_State <= ST_IDLE;
Func1FSM_State <= ST_IDLE;
Func2FSM_State <= ST_IDLE;
else
MainFSM_State <= MainFSM_NextState;
Func1FSM_State <= Func1FSM_NextState;
Func2FSM_State <= Func2FSM_NextState;
end if;
end process;
process(MainFSM_State, Input, ...,
Func1FSM_Output, Func1FSM_Return,
Func2FSM_Output, Func2FSM_Return)
begin
Func1FSM_Call <= '0';
Func2FSM_Call <= '0';
MainFSM_Output <= x"00";
case MainFSM_State is
when ST_IDLE =>
if (Input = '1') then
Func1FSM_Call <= '1';
MainFSM_NextState <= ST_FUNC1_EXECUTING;
end if;
when ST_FUNC1_EXECUTING =>
MainFSM_Output <= Func1FSM_Output;
if (Func1FSM_Return = '1') then
Func2FSM_Call <= '1';
end if;
....
end case;
end process;
Using big FSMs is also very fault-prone. 使用大型FSM也很容易出错。 So one goal of writing big FSMs should be readability, so you can find errors more easily.
因此,编写大型FSM的目标之一应该是可读性,这样您就可以更轻松地发现错误。
Don't use std_logic_arith, std_logic_unsigned while numeric_std is used. 使用numeric_std时,请勿使用std_logic_arith和std_logic_unsigned。 Use only numeric_std, that's adequate.
仅使用numeric_std,就足够了。
wait until
is not a synthesizeable statement. wait until
不是可综合的语句。 Use: 采用:
if rising_edge(clk) then ... end if;
Are your external inputs like reset_switch synchronized and debounced? 您的外部输入(例如reset_switch)是否已同步和去抖动? A signal name like reset_switch implies that this signal is raw ;)
像reset_switch这样的信号名称表示该信号是原始的;)
You can improve the readability of if..elsif..else..end if;
您可以提高
if..elsif..else..end if;
的可读性if..elsif..else..end if;
statements by using case statements (see line 230) 使用case语句的语句(请参见第230行)
You use masses of binary assignments like t_left_most <= "010111"; --23
您使用大量的二进制分配,例如
t_left_most <= "010111"; --23
t_left_most <= "010111"; --23
. t_left_most <= "010111"; --23
。 Maybe it's better to declare t_left_most with another type (eg a constrained natural), so you can use integer literals in your FSM. 也许最好用其他类型(例如自然约束)声明t_left_most ,以便可以在FSM中使用整数文字。 For exporting these signals to other modules the signal is converted back to std_logic_vector.
为了将这些信号导出到其他模块,信号被转换回std_logic_vector。 -> improved readability
->提高了可读性
Some times it's good to introduce constants eg 有时最好引入常量,例如
constant C_TOP_MOST : NATURAL := 0;
I would advice you to extract your counter memReadAddress
from your FSM. 我建议您从FSM中提取计数器
memReadAddress
。 Big FSMs should only generate flow-control signals, FSMs should not contain any data-flow logic (counters, multiplexers, ...). 大型FSM仅应生成流控制信号,FSM不应包含任何数据流逻辑(计数器,多路复用器等)。 So extract the counter to a separate process and add control signals to your big FSM.
因此,将计数器提取到一个单独的进程中,然后将控制信号添加到大型FSM中。
when T_block_1 => ReadAddressCounter_en <= '1';
Personally, I use prefixes like _rst, _en, _us, _inc, _dec for the counter control signals. 就个人而言,我为计数器控制信号使用诸如_rst,_en,_us,_inc,_dec之类的前缀。 _us stands for unsigned, because the my counters are unsigned counters and the value is converted to std_logic if needed.
_us代表无符号,因为我的计数器是无符号计数器,并且在需要时将值转换为std_logic。
Counter example with FSM 'remote control' signals: 带FSM“远程控制”信号的反例:
process(Clock) begin if rising_edge(Clock) then if ((Reset or MemAddressCounter_rst) = '1') then MemAddressCounter_us <= (others => '0'); else if (MemAddressCounter_load = '1') then MemAddressCounter_us <= to_unsigned(5, MemAddressCounter_us'length); elsif (MemAddressCounter_inc = '1') then MemAddressCounter_us <= MemAddressCounter_us + 1; end if; end if; end if; end process; MemAddress <= std_logic_vector(MemAddressCounter_us);
line 286 should not be synthesizable (I think Xilinx XST is not smart enough and if so, it's not predictable what XST would produce ...) 286行不应该是可综合的(我认为Xilinx XST不够智能,如果这样的话,就无法预测XST会产生什么...)
dataIn<=dataOut(39 downto conv_integer(T_left_most+1))&T_square&T_square&T_square&dataOut(conv_integer(T_right_most-1) downto 0);
So how can you fix the last point in the list of my hints? 那么,如何确定提示列表中的最后一点呢?
If you want a more detailed discussion on this points, please leave a comment and I will try to extend my answer. 如果您想在这点上进行更详细的讨论,请发表评论,我将尝试扩大答案。
So lets summarize line 286: 因此,让我们总结一下286行:
dataIn <= dataOut(39 downto conv_integer(T_left_most+1)) &
T_square & T_square & T_square &
dataOut(conv_integer(T_right_most-1) downto 0);
Your result consists of 3 parts: 您的结果包括3个部分:
This bit insertion can also be done by a bitwise set/clear operation: 该位插入也可以通过按位设置/清除操作来完成:
result <= input or set_mask;
result <= input or set_mask;
result <= input and not clear_mask;
result <= input and not clear_mask;
This can be combined to a bit override operation: 可以将其组合为位覆盖操作:
result <= (input and not override_mask) or override_value;
result <= (input and not override_mask) or override_value;
result <= (input and not override_mask) or (override_value and override_mask);
result <= (input and not override_mask) or (override_value and override_mask);
The latter must be used if you can not assume that override_value has only bits set within the range of override_mask. 如果您不能假定override_value仅在override_mask范围内设置了位,则必须使用后者。
The next step is to move T_square to the right position. 下一步是将T_square移到正确的位置。 Shifting bits in a fast way can be done by a barrel-shifter or a multiplier (DSP block).
可以通过桶形移位器或乘法器(DSP模块)来快速移位位。 Because your vector has 40 bits, a barrel-shifter is faster then a DSP block.
由于向量具有40位,因此桶形移位器比DSP块更快。
A barrel shifter of 64 bits has a 6 bit shift_value input. 64位的桶形移位器具有6位的shift_value输入。 Each bit of the input specifies if the value should be shifted by a power of two.
输入的每一位都指定该值是否应移位2的幂。
entity arith_BarrelShifter is
generic (
BITS : POSITIVE := 32
);
port (
Input : in STD_LOGIC_VECTOR(BITS - 1 downto 0);
ShiftAmount : in STD_LOGIC_VECTOR(log2ceilnz(BITS) - 1 downto 0);
Output : out STD_LOGIC_VECTOR(BITS - 1 downto 0)
);
end;
architecture rtl of arith_BarrelShifter is
constant STAGES : POSITIVE := log2ceilnz(BITS);
subtype T_INTERMEDIATE_RESULT is STD_LOGIC_VECTOR(BITS - 1 downto 0);
type T_INTERMEDIATE_VECTOR is array (NATURAL range <>) of T_INTERMEDIATE_RESULT;
signal IntermediateResults : T_INTERMEDIATE_VECTOR(STAGES downto 0);
begin
IntermediateResults(0) <= Input;
Output <= IntermediateResults(STAGES);
for i in 0 to STAGES - 1 generate
process(IntermediateResults(i), ShiftRotate, LeftRight, ArithmeticLogic)
begin
if (ShiftAmount(i) = '0') then
IntermediateResults(i + 1) <= IntermediateResults(i);
else
IntermediateResults(i + 1) <= IntermediateResults(i)((BITS - i**2 - 1) downto 0) & ((i**2 - 1) downto 0 => '0'); -- SLA, SLL
end if;
end process;
end generate;
end;
So now we can combine all steps: 现在,我们可以结合所有步骤:
override_value <= (39 downto 3 => '0') & (2 downto 0 => T_square);
override_mask <= (39 downto 3 => '0') & (2 downto 0 => '1');
shift_value : entity PoC.arith_BarrelShifter
generic map (
BITS => 40
)
port map (
Input => override_value,
ShiftAmount => T_left_most,
Output => shifted_value
);
shift_mask : entity PoC.arith_BarrelShifter
generic map (
BITS => 40
)
port map (
Input => override_mask,
ShiftAmount => T_left_most,
Output => shifted_mask
);
-- clear bits from source / set bits from value
dataIn <= (dataOut and not shifted_mask) or shifted_value;
I hope I made no mistakes :) 我希望我没有犯错:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.