我试图在斯巴达6上编写一个类似于公共汽车的i2c代码。我有一堆状态,我使用折页计数器的时间。
-- Timer --
TimesUp <= true when TmrCnt = 0 else
false when TmrCnt /= 0 else
false;
tmrProc: process(ClkxC, SetTmr, TmrInit)
begin
if (rising_edge(ClkxC)) then
if (SetTmr = '1') then
TmrCnt <= TmrInit;
elsif (TmrCnt > 0) then
TmrCnt <= TmrCnt - 1;
end if;
end if;
end process;问题是,我的状态机是在同一个时钟上时钟的,并且在一些短时间内,它只是像没有在时间中设置计时器一样快速地运行。
所以我试了一下:
-- Timer --
TimesUp <= true when TmrCnt = 0 else
false when TmrCnt /= 0 else
false;
tmrProc: process(ClkxC, SetTmr, TmrInit)
begin
if (SetTmr = '1') then
TmrCnt <= TmrInit;
elsif (rising_edge(ClkxC)) then
if (TmrCnt > 0) then
TmrCnt <= TmrCnt - 1;
end if;
end if;
end process;现在它模拟得很好,但是当我尝试实现时,我会收到一条错误消息,上面写着:
This design contains one or more registers/latches that are directly incompatible with the Spartan6 architecture. The two primary causes of this is either a register or latch described with both an asynchronous set and asynchronous reset, or a register or latch described with an asynchronous set or reset which however has an initialization value of the opposite polarity (i.e. asynchronous reset with an initialization value of 1).
我真的不知道如何使计时器负载足够快,而不刹车的规则斯巴达6。
发布于 2013-09-19 00:29:33
此警告已在斯巴达-6 FPGA的Xilinx WP309定位和重定向指南 P9-11中明确描述。
To reduce cost of the overall architecture, slices in Spartan-6 FPGAs do not have a REV
pin. As a result, flip-flops no longer implement both a set signal and a reset signal. In
addition, a register with a set or reset signal can only have an initialization value of
the same polarity. For example, a flip-flop with an asynchronous reset can only have an
initialization value of 0. 也就是说,当使用XilinxSpartan-6FPGAs时,以下类型的寄存器/锁存器是不推荐的:
______|______
| Set |
| |
---| D Q |--- -- 1. a register/latch with both ASYNCHRONOUS
| _ | set and reset signals
---|>Clk Q |o-- -- NOT RECOMMENDED
| |
| Reset |
|___________|
|
-- 2. a register/latch described with an ASYNCHRONOUS set/reset which
however has an initialization value of the opposite polarity
-- The default value of reg is 0 which is the left
-- bound value of the integer type definition.
signal reg: integer range 0 to 7; <-----
|
process (clk, reset) |___ opposite
begin | NOT RECOMMENDED
if (reset = '0') then |
reg <= 7; <-----
elsif ( rising_edge(clk) ) then
reg <= val;
end if;
end process;Xilinx推荐的解决方案:
1. Remove either the set or reset from all registers and latches
if not needed for required functionality
2. Modify the code in order to produce a synchronous set and/or
reset (both is preferred)
3. Ensure all registers have the same initialization value as the
described asynchronous set or reset polarity
4. Use the -async_to_sync option to transform the asynchronous
set/reset to synchronous operation
(timing simulation highly recommended when using this option)在您的设计中,可以将TmrCnt初始化为TmrInit,也可以向上计算TmrCnt。
发布于 2013-09-19 08:58:32
从第一个(同步)方法转移到第二个(异步集)很少是解决问题的正确方法;不管Spartan-6在重置逻辑上有多经济。事实上,我会以.为理由为他们辩护。“别那么做”。
相反,看一看语句“问题是,我的状态机在同一个时钟上运行,并且在某些短时间内,它只是像没有在时间中设置计时器一样快速地运行。”
首先,I2C信号的持续时间并不短,除非这是它的几百个MHz导数.
其次,VHDL做得很好的一件事就是同步设计,所以在没有重置计数器点的情况下,可以“突破”:可能是指这里的信号分配规则。
我怀疑这会导致状态机将SetTmr设置为在一个单独的进程中与计数器通信的问题;因此计数器在一个周期后看到SetTmr,而该周期延迟导致所观察到的错误行为,因为TimesUp在该周期中有错误的值。
有一个答案--我经常使用的一种模式--简单地将定时器卷到SM进程本身;然后直接设置它,保存握手逻辑和一个单独的进程。
StateMch : process(Clock)
begin
if rising_edge(Clock) then
-- default actions
if Timer > 0 then
Timer <= Timer - 1;
end if;
-- state machine
case State is
when Start_Wait =>
Timer <= My_Delay;
State <= Waiting;
when Waiting =>
if Timer = 0 then
State <= Done;
end if;
when others =>
State <= Start_Wait;
end case;
end if;
end process;除了更简单和(我发现)更容易理解比一个庞大的小进程集合,这允许几个州使用相同的计时器产生不同的延迟。
https://stackoverflow.com/questions/18881793
复制相似问题