谁能解释一下为什么我的计数有一个刻度的延迟,而我的总和有两个刻度的延迟?我是一个初学者,所以这对一些人来说可能是微不足道的,但我真的不明白问题所在。这模拟了单个类型的硬币存储实体在自动食品分配器的情况下应该如何表现。最初,我认为与计数相比,总和的1个节拍延迟可能是由于2个不同的时钟进程中的2个信号,但似乎不是这样。考虑到这里需要一个顺序代码,我不知道如何至少为每个信号减少1个滴答的总延迟。如果两者都没有延迟,那将是最理想的。感谢您查看此问题。
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.fixed_point_pkg.all;
entity single_coin_type_storage is
generic(INIT_COUNT : natural;
--Number of coins loaded at maintenance.
INIT_SUM : unsigned(15 downto 0);
--Value of the coins loaded at maintenance.
COIN_VAL : unsigned(15 downto 0));
--Value of a single coin.
port(clk : in std_logic;
--System clock.
reset : in std_logic;
--System reset.
en : in std_logic;
--Enable input. When low, no register updates can
--happen and the output of >>count<< should be zero.
add_coin : in std_logic;
--Signals that a coin is being added.
rem_coin : in std_logic;
--Signals that a coin is being removed.
count : out std_logic_vector(4 downto 0);
--Number of coins currently stored. If >>en<< is low,
--must be zero.
sum : out std_logic_vector(15 downto 0);
--Value of all coins currently stored. Should be
--output at all times, regardless of >>en<<.
fault : out std_logic);
--Signals that an attempt to insert a coin into a full
--storage unit or to remove it from an empty unit is
--being made.
end entity single_coin_type_storage;
architecture rtl of single_coin_type_storage is
signal counter_reg: unsigned(5 downto 0);
signal en_vec: std_logic_vector(4 downto 0);
signal sum_reg: unsigned(15 downto 0);
signal y_count : unsigned(5 downto 0);
signal y_sum : unsigned(15 downto 0);
signal ovf ,internal_en: std_logic;
begin
y_count <= counter_reg +1 when (add_coin ='1') else
counter_reg - 1 when (rem_coin ='1') else
counter_reg ;
ovf <= y_count(5);
internal_en <= en and (not ovf);
en_vec <= (others=>en);
y_sum <= sum_reg + COIN_VAL when (add_coin ='1') else
sum_reg - COIN_VAL when (rem_coin ='1') else y_sum ;
CNT_REG_P: process (clk)
begin
if (clk'event and clk ='1') then
if (reset ='1') then
counter_reg <= to_unsigned(INIT_COUNT,counter_reg'length);
elsif (en ='1') then
counter_reg <= y_count;
end if;
end if;
end process;
SUM_REG_P: process (clk)
begin
if (clk'event and clk ='1') then
if (reset ='1') then
sum_reg <= INIT_SUM;
elsif (en ='1') then
sum_reg <= y_sum;
end if;
end if;
end process;
count <= en_vec and std_logic_vector(counter_reg(4 downto 0));
fault <= ovf and en;
sum<= std_logic_vector(sum_reg);
end architecture rtl;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
package fixed_point_pkg is
--There are up to 31 coins of each type, which gives the maximum value
--of 31 * 8.7 = 269.7. Hence we need 9 bits for the whole part. The
--smallest fraction we need to represent is 1/5, which is decently
--approximated by 1/8 + 1/16 + 1/128 (31 * error < 0.2). Hence, we
--need 7 more bits for the fractional part.
--The representation is thus 9:7.
constant fifth : unsigned(15 downto 0) := x"0019";
--0000 0000 0.001 1001
constant half : unsigned(15 downto 0) := x"0040";
--0000 0000 0.100 0000
constant one : unsigned(15 downto 0) := x"0080";
--0000 0000 1.000 0000
constant two : unsigned(15 downto 0) := x"0100";
--0000 0001 0.000 0000
constant five : unsigned(15 downto 0) := x"0280";
--0000 0010 1.000 0000
function fixed_to_float(fixed : std_logic_vector) return real;
--Converts a 9.7 16-bit fixed point number to a real.
function float_to_fixed(float : real) return unsigned;
--Converts a real to a 9.7 16-bit fixed point number.
function float_eq(a : real; b : real) return boolean;
--Compares two floats by truncating them to two decimal points.
type init_count_t is array(0 to 4) of natural;
--Represents the numbers of coins of each type loaded at maintenance.
--The first element corresponds to the 20 cents coins and the last to 5 franc ones.
type init_sum_t is array(0 to 4) of unsigned(15 downto 0);
--Represents the total values of the coins of each type loaded at maintentance.
--The order is the same as for >>init_count_t<<.
constant main_init_counts : init_count_t := (20, 10, 10, 5, 0);
constant main_init_sums : init_sum_t := (x"0200", x"0280", x"0500", x"0500", x"0000");
end package fixed_point_pkg;
package body fixed_point_pkg is
function fixed_to_float(fixed : std_logic_vector) return real is
type val_t is array(15 downto 0) of real;
constant vals : val_t := (256.0, 128.0, 64.0, 32.0, 16.0, 8.0, 4.0, 2.0, 1.0,
0.5, 0.25, 0.125, 0.0625, 0.03125, 0.015625, 0.0078125);
variable sum : real := 0.0;
begin
for i in 0 to 15 loop
if fixed(i) = '1' then
sum := sum + vals(i);
end if;
end loop;
return sum;
end function fixed_to_float;
function float_to_fixed(float : real) return unsigned is
begin
return to_unsigned(integer(trunc(float * 128.0)), 16);
end function float_to_fixed;
function float_eq(a : real; b : real) return boolean is
variable a_int, b_int : integer;
begin
a_int := integer(trunc(a * 100.0));
b_int := integer(trunc(b * 100.0));
return a_int = b_int;
end function float_eq;
end package body fixed_point_pkg;
发布于 2020-06-05 18:02:05
y_count是寄存器的输入,由else counter_reg表示。y_sum是一个锁存器,由else y_sum指示,然后注册。将else y_sum替换为else sum_reg。
发布于 2020-06-07 07:46:41
试着画出你所描述的硬件的框图,寄存器在哪里,多路复用器在哪里,加法器在哪里等等。然后看看你的工具是否支持rtl网表视图,这样你就可以将你认为写的东西和实际写的东西进行比较。如果您在那里看到任何锁存器,请查看是否可以重写代码/更改设计以将这些更改为寄存器。锁存FPGA不能很好地搭配。然后,你可以按照这两个信号的路径来计算每个信号“相遇”的寄存器数量。
https://stackoverflow.com/questions/62115885
复制相似问题