1

任务是制作一个使用 FSM 的 4 位乘法器。步骤是 1) 乘 2) 移位 3) 加。

  1011   (this is 11 in binary)
 x 1110   (this is 14 in binary)
 ======
   0000   (this is 1011 x 0)
  1011    (this is 1011 x 1, shifted 1 position to the left)
 1011     (this is 1011 x 1, shifted 2 positions to the left)
1011      (this is 1011 x 1, shifted three positions to the left)
======

10011010(这是二进制的 154)

http://en.wikipedia.org/wiki/Binary_multiplier

这是我的代码:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity test is
    Port ( CLK : in  STD_LOGIC;
       RESET : in  STD_LOGIC;
       Input : in  STD_LOGIC_VECTOR (3 downto 0);
       Confirm : in  STD_LOGIC;
       Output : out  STD_LOGIC_VECTOR (7 downto 0));
end test;

architecture Behavioral of test is

type state is (R,S0,S1,S2,S3,S4);
signal pstate, nstate: state;
signal A_sig, B_sig: STD_LOGIC_VECTOR(3 downto 0);

begin
process(pstate,Confirm,Input)
variable temp_var: STD_LOGIC_VECTOR(3 downto 0);
variable tempMult_var,tempProd_var: STD_LOGIC_VECTOR(7 downto 0);
begin
    case pstate is
        when R =>
            nstate <= S0;
            tempMult_var := (others => '0');
            tempProd_var := (others => '0');

            A_sig <= (others => '0');
            B_sig <= (others => '0');

            Output <= (others => '0');
        when S0 =>
            nstate <= S0;

            if (Confirm = '1') then
                A_sig <= Input;
                nstate <= S1;
            end if;
        when S1 =>
            nstate <= S1;

            if (Confirm = '0') then
                nstate <= S2;
            end if;
        when S2 =>
            nstate <= S2;

            if (Confirm = '1') then
                B_sig <= Input;
                nstate <= S3;
            end if;
        when S3 =>
            nstate <= S3;

            if (Confirm = '0') then
                nstate <= S4;
            end if;
        when S4 =>
            nstate <= S0;

            for x in 0 to 3 loop
                temp_var := (A_sig AND (B_sig(x)&B_sig(x)&B_sig(x)&B_sig(x) ) );
                tempMult_var := "0000" & temp_var;
                if (x=0) then tempMult_var := tempMult_var;
                    elsif (x=1) then tempMult_var := tempMult_var(6 downto 0)&"0";
                    elsif (x=2) then tempMult_var := tempMult_var(5 downto 0)&"00";
                    elsif (x=3) then tempMult_var := tempMult_var(4 downto 0)&"000";        
                end if;
                tempProd_var := tempProd_var + tempMult_var;
            end loop;

            Output <= tempProd_var;
            tempProd_var := (others => '0');
    end case;
end process;

process(CLK,RESET)
begin
    if RESET = '1' then
        pstate <= R;
    elsif rising_edge(CLK) then
        pstate <= nstate;
    end if;
end process;
end Behavioral;

这是警告

after "Synthesize - XST"
WARNING:Xst - Property "use_dsp48" is not applicable for this technology.
WARNING:Xst:737 - Found 4-bit latch for signal <B_sig>.
WARNING:Xst:737 - Found 8-bit latch for signal <Output>.
WARNING:Xst:737 - Found 4-bit latch for signal <A_sig>.

after "Implement Design"
WARNING:Route:447 - CLK Net:A_sig_not0001 may have excessive skew because 
WARNING:Route:447 - CLK Net:B_sig_not0001 may have excessive skew because 

after "Generate Programming File"
WARNING:PhysDesignRules:372 - Gated clock. Clock net A_sig_not0001 is sourced by
WARNING:PhysDesignRules:372 - Gated clock. Clock net B_sig_not0001 is sourced by
WARNING:PhysDesignRules:372 - Gated clock. Clock net Output_or0000 is sourced by

模拟是正确的,但实际电路板没有正确的输出。可能是什么问题?

4

2 回答 2

1

我的谦虚建议:

将您的两个进程组合​​成一个时钟进程。

这样,您就可以避免一整类异步逻辑错误,这些错误对于初学者来说很容易造成痛苦的追查。

于 2012-09-10T11:58:26.990 回答
0

此外,每当您看到有关锁存器或门控时钟的警告时,请重新访问您的代码 - 两者都清楚地表明某些事情很可能是错误的。

锁存器通常来自组合过程,其中仅在某些情况下分配信号。例如A_sig,在 S0 中没有分配,如果confirm = 0,则将导致推断出一个锁存器。在这种情况下,只要确保A_sig始终设置为某个值,无论控制信号值的组合如何。

在这种情况下,门控时钟可能来自您相当复杂的组合过程,但主要来自为同步过程提供时钟的逻辑生成的信号。这可能会导致各种问题(高 FPGA 时钟线使用率和时序/路由问题),特别是如果您不知道您正在创建额外的时钟域。这可以通过在主(全局或本地)系统时钟上运行有问题的进程并在必要时使用时钟启用来缩小它来避免。

于 2012-10-01T17:00:13.960 回答