Multiple read of register in VHDL and encapsulation leads to wrong value - vhdl

I currently confront one problem with reading two registers and send their value via proxy to tile on FPGA. There are three input channels for encoded signals which consis of pulses with frequency of 50khz, then the signal were sampled by a local 100Mhz clock on FPGA board. In the module two channels were counted for their pulses and I use bit shift for encapsulation to put the read value from two counter into one 32bits std_bit_vector to send via proxy.
If I only transfer counting value of one channel and sent them via proxy signals, it behaviors always correctly. However when reading two counting value from two register and doing the encapsulation, the 16 higher bits of the shifted value is always increasing faster than it supposed to be. In another word, counting process ifself is correct while there is also no problems with communication between counting module and tile.
I dont know the problem is caused by the process reading too fast from two registers and leads to synchronization problem. One channel input signal only increases by one per 500 counts, while another counting 500 per rotation.One rotation is controlled by hand on the encoder (THen u can imagine the low frequency of the input signals)
THen encapsulation were put in last two lines of the module.
THanks in advance.
THe module of counting is design as following:
library rdt_dtl_proxy_targetlib;
use rdt_dtl_proxy_targetlib.rdt_dtl_proxy_target_cmp_pkg.all;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_ARITH.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
entity dtl_pmod_rotary is
generic (
WIDTH_DTL_CMD_ADDR : natural:= 32;
WIDTH_DTL_CMD_BLOCK_SIZE : natural:= 5;
WIDTH_DTL_DATA : natural:= 32;
WIDTH_DTL_WR_MASK : natural:= 4
);
port (
clk : in std_logic;
rst_n : in std_logic;
rotary_a : in std_logic;
rotary_b : in std_logic;
rotary_i : in std_logic;
dtl_cmd_valid_t_proxy0 : in std_logic;
dtl_cmd_accept_t_proxy0 : out std_logic;
dtl_cmd_addr_t_proxy0 : in std_logic_vector(WIDTH_DTL_CMD_ADDR - 1 downto 0);
dtl_cmd_read_t_proxy0 : in std_logic;
dtl_cmd_block_size_t_proxy0 : in std_logic_vector(WIDTH_DTL_CMD_BLOCK_SIZE - 1 downto 0);
dtl_wr_valid_t_proxy0 : in std_logic;
dtl_wr_last_t_proxy0 : in std_logic;
dtl_wr_accept_t_proxy0 : out std_logic;
dtl_wr_data_t_proxy0 : in std_logic_vector(WIDTH_DTL_DATA - 1 downto 0);
dtl_wr_mask_t_proxy0 : in std_logic_vector(WIDTH_DTL_WR_MASK - 1 downto 0);
dtl_rd_last_t_proxy0 : out std_logic;
dtl_rd_valid_t_proxy0 : out std_logic;
dtl_rd_accept_t_proxy0 : in std_logic;
dtl_rd_data_t_proxy0 : out std_logic_vector(WIDTH_DTL_DATA - 1 downto 0)
);
end dtl_pmod_rotary;
architecture rtl of dtl_pmod_rotary is
signal dtl_rd_data_15 : std_logic_vector(WIDTH_DTL_DATA - 1 downto 0);
signal dtl_rd_accept_14 : std_logic;
signal dtl_cmd_block_size_6 : std_logic_vector(WIDTH_DTL_CMD_BLOCK_SIZE - 1 downto 0);
signal dtl_wr_data_10 : std_logic_vector(WIDTH_DTL_DATA - 1 downto 0);
signal dtl_cmd_read_5 : std_logic;
signal dtl_rd_last_12 : std_logic;
signal dtl_rst_n_1 : std_logic;
signal dtl_wr_valid_7 : std_logic;
signal dtl_wr_accept_9 : std_logic;
signal dtl_wr_last_8 : std_logic;
signal dtl_cmd_addr_4 : std_logic_vector(WIDTH_DTL_CMD_ADDR - 1 downto 0);
signal dtl_cmd_valid_2 : std_logic;
signal dtl_clk_0 : std_logic;
signal dtl_rd_valid_13 : std_logic;
signal dtl_wr_mask_11 : std_logic_vector(WIDTH_DTL_WR_MASK - 1 downto 0);
signal dtl_cmd_accept_3 : std_logic;
-- signals for counting
signal cnt_r : std_logic_vector(WIDTH_DTL_DATA-1 downto 0) := X"00000000";
signal cnt_r_a : std_logic_vector(WIDTH_DTL_DATA-1 downto 0) := X"00000000";
signal cnt_r_b : std_logic_vector(WIDTH_DTL_DATA-1 downto 0) := X"00000000";
signal cnt_r_i : std_logic_vector(WIDTH_DTL_DATA-1 downto 0) := X"00000000";
signal cnt_nxt_a : std_logic_vector(WIDTH_DTL_DATA-1 downto 0) := X"00000000";
signal cnt_nxt_b : std_logic_vector(WIDTH_DTL_DATA-1 downto 0) := X"00000000";
signal cnt_nxt_i : std_logic_vector(WIDTH_DTL_DATA-1 downto 0) := X"00000000";
signal cnt_ref_i : std_logic_vector(WIDTH_DTL_DATA-1 downto 0) := X"00000000";
signal rotary_a_r : std_logic; --register storing data from rotary_a.
signal rotary_a_2r : std_logic; --register storing data from rotary_a_r
signal rotary_b_r : std_logic; --register storing data from rotary_b.
signal rotary_b_2r : std_logic; --register storing data from rotary_b_r
signal rotary_i_r : std_logic; --register storing data from rotary_i.
signal rotary_i_2r : std_logic; --register storing data from rotary_i_r
begin
dtl_clk_0 <= clk;
dtl_rst_n_1 <= rst_n;
dtl_cmd_valid_2 <= dtl_cmd_valid_t_proxy0;
dtl_cmd_accept_t_proxy0 <= dtl_cmd_accept_3;
dtl_cmd_addr_4 <= dtl_cmd_addr_t_proxy0;
dtl_cmd_read_5 <= dtl_cmd_read_t_proxy0;
dtl_cmd_block_size_6 <= dtl_cmd_block_size_t_proxy0;
dtl_wr_valid_7 <= dtl_wr_valid_t_proxy0;
dtl_wr_last_8 <= dtl_wr_last_t_proxy0;
dtl_wr_accept_t_proxy0 <= dtl_wr_accept_9;
dtl_wr_data_10 <= dtl_wr_data_t_proxy0;
dtl_wr_mask_11 <= dtl_wr_mask_t_proxy0;
dtl_rd_last_t_proxy0 <= dtl_rd_last_12;
dtl_rd_valid_t_proxy0 <= dtl_rd_valid_13;
dtl_rd_accept_14 <= dtl_rd_accept_t_proxy0;
dtl_rd_data_t_proxy0 <= dtl_rd_data_15;
-- Begin child instances
proxy0 : rdt_dtl_proxy_target
generic map (
DTL_DATA_WIDTH => WIDTH_DTL_DATA,
DTL_ADDR_WIDTH => WIDTH_DTL_CMD_ADDR,
DTL_BLK_SIZE_WIDTH => WIDTH_DTL_CMD_BLOCK_SIZE,
DTL_WR_MASK_WIDTH => WIDTH_DTL_WR_MASK
)
port map (
dtl_clk => dtl_clk_0,
dtl_rst_n => dtl_rst_n_1,
dtl_cmd_accept_t => dtl_cmd_accept_3,
dtl_cmd_addr_t => dtl_cmd_addr_4,
dtl_cmd_block_size_t => dtl_cmd_block_size_6,
dtl_cmd_read_t => dtl_cmd_read_5,
dtl_cmd_valid_t => dtl_cmd_valid_2,
dtl_rd_accept_t => dtl_rd_accept_14,
dtl_rd_data_t => dtl_rd_data_15,
dtl_rd_last_t => dtl_rd_last_12,
dtl_rd_valid_t => dtl_rd_valid_13,
dtl_wr_accept_t => dtl_wr_accept_9,
dtl_wr_data_t => dtl_wr_data_10,
dtl_wr_last_t => dtl_wr_last_8,
dtl_wr_mask_t => dtl_wr_mask_11,
dtl_wr_valid_t => dtl_wr_valid_7,
cmd_accept => '1', --target accept handshake,input port of Proxy
cmd_addr => open,
cmd_block_size => open,
cmd_read => open, --output port of Proxy
cmd_valid => open, --output port of Proxy
rd_accept => open, --output port of Proxy, return the accept info from initializer
--rd_data => x"00000003", --test value
rd_data => cnt_r, --input port of proxy, for sending the counter value
rd_last => '1',
rd_valid => '1',
wr_accept => '0', --return value to Proxy indicating prepared for receiving written data from initiator
wr_data => open, --receive data from Proxy that written by initializer
wr_last => open,
wr_mask => open,
wr_valid => open
);
-- Counting pulses
-- combinatorial process
comb_counter_process_a : process(rotary_a_r, rotary_a_2r)
begin
if rotary_a_r = '1' and rotary_a_2r = '0' then
cnt_nxt_a <= cnt_r_a + 1;
else
cnt_nxt_a <= cnt_r_a;
end if;
end process;
-- sequential process with synchronous reset
seq_counter_process_a : process(clk)
begin
if rising_edge(clk) then
if rst_n = '0' then
cnt_r_a <= (others => '0');
rotary_a_r <= '0';
rotary_a_2r <= '0';
else
-- registering
cnt_r_a <= cnt_nxt_a ;
rotary_a_2r <= rotary_a_r;
rotary_a_r <= rotary_a;
--cnt_r <= cnt_r_a(8 downto 0);
end if;
end if;
end process;
comb_counter_process_b : process(rotary_b_r, rotary_b_2r)
begin
if rotary_b_r = '1' and rotary_b_2r = '0' then
cnt_nxt_b <= cnt_r_b + 1;
else
cnt_nxt_b <= cnt_r_b;
end if;
end process;
-- sequential process with synchronous reset
seq_counter_process_b : process(clk)
begin
if rising_edge(clk) then
if rst_n = '0' then
cnt_r_b <= (others => '0');
rotary_b_r <= '0';
rotary_b_2r <= '0';
else
-- registering
cnt_r_b <= cnt_nxt_b;
rotary_b_2r <= rotary_b_r;
rotary_b_r <= rotary_b;
--cnt_r(31 downto 16) <= X"ABCD";
end if;
end if;
end process;
comb_counter_process_i : process(rotary_i_r, rotary_i_2r)
begin
if rotary_i_r = '1' and rotary_i_2r = '0' then
cnt_nxt_i <= cnt_r_i + 1;
else
cnt_nxt_i <= cnt_r_i;
end if;
end process;
-- sequential process with synchronous reset
seq_counter_process_i : process(clk)
begin
if rising_edge(clk) then
if rst_n = '0' then
cnt_r_i <= (others => '0');
rotary_i_r <= '0';
rotary_i_2r <= '0';
else
-- registering
cnt_r_i <= cnt_nxt_i;
rotary_i_2r <= rotary_i_r;
rotary_i_r <= rotary_i;
--cnt_r(15 downto 0) <= X"1234"; --the digits for cnt_r_i may change
end if;
end if;
end process;
cnt_r(31 downto 16) <= cnt_r_b(15 downto 0);
cnt_r(15 downto 0) <= cnt_r_i(15 downto 0);
end rtl;

Related

Why won't a VHDL "inout" signal be assigned a value when used as an output

I have a VHDL description for a bridge, and the bidirectional signal "mem_data_port0" is not getting assigned any value regardless of what I write to it. The pins on the FPGA are assigned accordingly, but no output.
I have the code below (its for an FPGA going into a larger system, so comments will reflect other system components that are not the FPGA)
FYI: The FPGA is a Lattice LCMXO2-7000HC
Any tips on assigning "mem_data_port0"?
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
--use ieee.std_logic_signed.all;
use ieee.std_logic_arith.all;
use ieee.numeric_std.all;
library machxo2;
use machxo2.all;
entity SinglePhasePowerAnalyzerBridge is
port(
output0 : out std_logic; -- dummy, unassigned outputs
output1 : out std_logic;
output2 : out std_logic;
output3 : out std_logic;
output4 : out std_logic;
output5 : out std_logic;
output6 : out std_logic;
output7 : out std_logic;
accq_data_in : in std_logic_vector (15 downto 0); -- accquisition data in
accq_clk : in std_logic; -- accquisition clock in
accq_data_ready : in std_logic; -- data ready in 0: sending voltage/current data, 1: sending frequency data
accq_reset : in std_logic; -- accquisition reset (active low)
accq_voltage_current : in std_logic; -- accquisition select for voltage and current 0: voltage, 1: current
buffer_data_port0 : out std_logic_vector (15 downto 0); -- buffer data
buffer_address_port0 : in std_logic_vector(12 downto 0); -- buffer address low bits
buffer_address_high_port0 : in std_logic_vector(2 downto 0); -- buffer address high bits
buffer_high_byte_en_port0 : in std_logic; -- high byte enable
buffer_low_byte_en_port0 : in std_logic; -- low byte enable
buffer_write_en_port0 : in std_logic; -- write enable
buffer_output_en_port0 : in std_logic; -- output enable
buffer_memory_en_port0 : in std_logic; -- memory enable
buffer_interrupt_out : out std_logic;
-- pins going to external SRAM memory
mem_data_port0 : inout std_logic_vector (15 downto 0);
mem_address_port0 : out std_logic_vector(12 downto 0);
mem_address_high_port0 : out std_logic_vector (3 downto 0);
mem_memory_en_port0 : out std_logic := '1';
mem_output_en_port0 : out std_logic := '1';
mem_write_en_port0 : out std_logic := '1';
mem_high_byte_en_port0 : out std_logic := '0';
mem_low_byte_en_port0 : out std_logic := '0';
debug_out : out std_logic -- debug output
);
end SinglePhasePowerAnalyzerBridge;
architecture rtl of SinglePhasePowerAnalyzerBridge is
signal frequency_storage_buffer : std_logic_vector (15 downto 0); -- frequency buffer
signal voltage_storage_pointer : integer range 0 to 8191;
signal current_storage_pointer : integer range 0 to 8191;
signal signal_accq_data_in : std_logic_vector (15 downto 0);
signal signal_accq_clk : std_logic;
signal signal_inverse_accq_clk : std_logic;
signal signal_accq_data_ready : std_logic;
signal signal_accq_reset : std_logic;
signal signal_accq_voltage_current : std_logic;
signal signal_delayed_inverse_accq_clk : std_logic;
signal signal_buffer_data_port0 : std_logic_vector (15 downto 0);
signal signal_buffer_address_port0 : std_logic_vector(12 downto 0);
signal signal_buffer_address_high_port0 : std_logic_vector(2 downto 0);
signal signal_buffer_high_byte_en_port0 : std_logic;
signal signal_buffer_low_byte_en_port0 : std_logic;
signal signal_buffer_write_en_port0 : std_logic;
signal signal_buffer_output_en_port0 : std_logic;
signal signal_buffer_memory_en_port0 : std_logic;
begin
signal_accq_data_in <= accq_data_in; -- connect all the pins to internal signals
signal_accq_clk <= accq_clk;
signal_accq_data_ready <= accq_data_ready;
signal_accq_reset <= accq_reset;
signal_accq_voltage_current <= accq_voltage_current;
signal_inverse_accq_clk <= not signal_accq_clk;
--debug_out <= signal_delayed_inverse_accq_clk;
signal_buffer_address_port0 <= buffer_address_port0;
signal_buffer_address_high_port0 <= buffer_address_high_port0;
signal_buffer_high_byte_en_port0 <= buffer_high_byte_en_port0;
signal_buffer_low_byte_en_port0 <= buffer_low_byte_en_port0;
signal_buffer_write_en_port0 <= buffer_write_en_port0;
signal_buffer_output_en_port0 <= buffer_output_en_port0;
signal_buffer_memory_en_port0 <= buffer_memory_en_port0;
buffer_interrupt_out <= not signal_accq_data_ready;
output2 <= signal_accq_data_ready; -- dummy outputs, so the input pins are not left uncommected
output3 <= signal_accq_clk;
output4 <= signal_accq_reset;
output5 <= signal_accq_voltage_current;
general_event : process(signal_accq_clk, signal_accq_data_ready, signal_accq_data_in, signal_accq_voltage_current, signal_accq_reset,
signal_buffer_memory_en_port0, signal_buffer_output_en_port0, signal_buffer_write_en_port0, signal_buffer_address_high_port0, signal_buffer_address_port0,
signal_buffer_data_port0, frequency_storage_buffer, signal_accq_reset, signal_accq_data_ready, voltage_storage_pointer, current_storage_pointer)
begin
if(signal_accq_data_ready = '0') then -- when data from the acquisition controller comes in
mem_output_en_port0 <= '1'; -- disable memory output
mem_memory_en_port0 <= '0'; -- enable memory
mem_write_en_port0 <= signal_inverse_accq_clk; -- send the acquisition clock to the memory write enable pin
if(signal_accq_reset = '1') then -- if reset is not activated...
accq_clk_edge : if(rising_edge(signal_accq_clk)) then -- process on clock rising edge
if(signal_accq_voltage_current = '1') then -- if sending current data
mem_data_port0 <= signal_accq_data_in; -- store the data in the current buffer
mem_address_port0 <= std_logic_vector(to_unsigned(current_storage_pointer, 13));
mem_address_high_port0 <= "0001"; -- sending current data to memory
current_storage_pointer <= (current_storage_pointer + 1); -- increment the counter
elsif (signal_accq_voltage_current = '0') then -- do the same if sending voltage data
--mem_data_port0 <= signal_accq_data_in; -- store the data in the voltage buffer
mem_data_port0 <= "1111111111111111";
mem_address_port0 <= std_logic_vector(to_unsigned(voltage_storage_pointer, 13));
mem_address_high_port0 <= "0000"; -- sending voltage data to memory
voltage_storage_pointer <= (voltage_storage_pointer + 1); -- increment the counter
end if;
end if accq_clk_edge;
else -- if reset is activated...
voltage_storage_pointer <= 0; -- reset everything to 0
current_storage_pointer <= 0; -- reset everything to 0
end if;
--end process accq_event;
elsif (signal_accq_data_ready = '1') then -- if data ready is high, the buffer is in read mode
mem_data_port0 <= "ZZZZZZZZZZZZZZZZ"; -- set memory data lines to input, or read mode
mem_write_en_port0 <= '1'; -- disable writing to the memory
mem_output_en_port0 <= '0'; -- enable memory output
mem_address_port0 <= signal_buffer_address_port0; -- select the appropriate addreess
mem_address_high_port0 (2 downto 0) <= signal_buffer_address_high_port0; -- do the same with the high bits
if(rising_edge(signal_accq_clk) and signal_accq_reset = '1') then -- if the accquisition MCU is writing with the data ready pin high
frequency_storage_buffer <= signal_accq_data_in; -- store the frequency value that it's sending
end if;
if(signal_accq_reset = '0') then -- reset as before if reset is enabled
voltage_storage_pointer <= 0; -- reset everything to 0
current_storage_pointer <= 0; -- reset everything to 0
end if;
if(signal_buffer_memory_en_port0 = '0' and signal_buffer_write_en_port0 = '1' and signal_accq_data_ready = '1' and signal_accq_reset = '1') then -- memory enabled and write enable high...
case signal_buffer_address_high_port0 is
when "000" => signal_buffer_data_port0 <= mem_data_port0; -- output data to downstream MCUs as needed
when "001" => signal_buffer_data_port0 <= mem_data_port0;
when "010" => signal_buffer_data_port0 <= frequency_storage_buffer;
when "011" => signal_buffer_data_port0 <= std_logic_vector(to_unsigned(voltage_storage_pointer, 16));
when "100" => signal_buffer_data_port0 <= std_logic_vector(to_unsigned(current_storage_pointer, 16));
when "111" => signal_buffer_data_port0 <= "1010000001010110"; -- 0xA056
when others=>
end case;
end if;
if(signal_buffer_output_en_port0 = '0') then
--buffer_data_port0(7 downto 0) <= signal_buffer_data_port0 (15 downto 8);
--buffer_data_port0(15 downto 8) <= signal_buffer_data_port0 (7 downto 0);
buffer_data_port0 <= signal_buffer_data_port0;
else
buffer_data_port0 <= "ZZZZZZZZZZZZZZZZ";
end if;
end if;
end process general_event;
output6 <= signal_buffer_high_byte_en_port0;
output7 <= signal_buffer_low_byte_en_port0;
end rtl;
I've tried your code on Modelsim. Although I can't comment on the correctness of mem_data_port0's behavior, it does get assigned values depending on the other relevant signals, so for the out direction it works.
If you're talking about the fact that you cannot assign values to it from outside, all I could think of is that you forgot to assign it the high impedance in input mode, but you do, so that's out.
An explanation could be that your entity is not the top level entity, which would render inout ports unusable (inout has no meaning inside the FPGA, only at the design's top level).

VHDL State Machine Problems - Repeats States

We are building a processor for our final project. The control unit is a state machine, but it seems to get stuck in states for longer than it should, and thus it repeats instructions.
We are using Vivado 2015.4 and the Nexys4 board.
So, with a single line of instructions to store a value onto the 7-segments loaded up into the instruction memory, the states go:
Fetch =>
Fetch =>
Fetch =>
L_S_D (Load/Store Decode) =>
L_S_E (Load/Store Execute) =>
S_Mem (Store Memory Access) =>
Fetch =>
L_S_D =>
L_S_E =>
S_Mem =>
Fetch =>
L_S_D =>
L_S_E =>
Fetch (forever)
On the two complete run-throughs, the seven-segments display. On the third, incomplete run-through, they do not.
I'm attaching the state machine (relevant states) and the program counter-related code, because I think that's where the problem is.
State machine:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity Fred is
Port ( Inst : in STD_LOGIC_vector (31 downto 21);
clk : in std_logic;
rst : in std_logic;
Reg2Loc : out std_logic;
ALUSRC : out std_logic;
MemtoReg : out std_logic;
RegWrite : out std_logic;
Branch : out std_logic;
ALUOp : out std_logic_vector (1 downto 0);
UnconB : out std_logic;
en : out std_logic;
wea : out std_logic;
PCWrite : out std_logic;
REGCEA : out std_logic;
LEDCode : out std_logic_vector (4 downto 0));
end Fred;
architecture Behavioral of Fred is
Type type_fstate is (Fetch, L_S_D, L_S_E, L_Mem, S_Mem,
L_WB, R_I_D, I_E, R_E, I_WB, R_WB, B_E, CBZ_D, B_WB, CBZ_E,
CBZ_WB);
attribute enum_encoding : string;
attribute enum_encoding of type_fstate : type is "one-hot";
signal current_state : type_fstate;
signal next_state : type_fstate;
begin
clockprocess : process (clk, rst, current_state)
begin
if rst = '1' then
next_state <= Fetch;
elsif clk'EVENT and clk = '1' then
next_state <= current_state;
end if;
end process clockprocess;
state_logic: process (next_state)
begin
case next_state is
when Fetch => --00001
if ((Inst = "11111000010")) then --LDUR
current_state <= L_S_D;
elsif ((Inst = "11111000000")) then --STUR
current_state <= L_S_D;
--Additional State Logic Here
else
current_state <= Fetch;
end if;
when L_S_D => --00010
current_state <= L_S_E;
when L_S_E => --00011
if ((Inst = "11111000010")) then
current_state <= L_Mem;
elsif ((Inst = "11111000000")) then
current_state <= S_Mem;
end if;
when S_Mem => --00110
current_state <= Fetch;
--Additional States Here
when others =>
current_state <= Fetch;
end case;
end process state_logic;
output_logic : process (next_state)
begin
case next_state is
when Fetch =>
Reg2Loc <= '0';
ALUSRC <= '0';
MemtoReg <= '0';
RegWrite <= '0';
Branch <= '0';
ALUOp <= "00";
UnconB <= '0';
en <= '0';
wea <= '0';
PCWrite <= '0';
REGCEA <= '1';
LEDCode <= "00001";
when L_S_D =>
Reg2Loc <= '1';
ALUSRC <= '0';
MemtoReg <= '0';
RegWrite <= '0';
Branch <= '0';
ALUOp <= "00";
UnconB <= '0';
en <= '0';
wea <= '0';
PCWrite <= '0';
REGCEA <= '0';
LEDCode <= "00010";
when L_S_E =>
Reg2Loc <= '1';
ALUSRC <= '1';
MemtoReg <= '0';
RegWrite <= '0';
Branch <= '0';
ALUOp <= "00";
UnconB <= '0';
en <= '0';
wea <= '0';
PCWrite <= '1';
REGCEA <= '0';
LEDCode <= "00011";
when S_Mem =>
Reg2Loc <= '1';
ALUSRC <= '1';
MemtoReg <= '0';
RegWrite <= '0';
Branch <= '0';
ALUOp <= "00";
UnconB <= '0';
en <= '1';
wea <= '1';
PCWrite <= '0';
REGCEA <= '0';
LEDCode <= "00110";
--Additional State Outputs Here
when others =>
Reg2Loc <= '0';
ALUSRC <= '0';
MemtoReg <= '0';
RegWrite <= '0';
Branch <= '0';
ALUOp <= "00";
UnconB <= '0';
en <= '0';
wea <= '0';
PCWrite <= '0';
REGCEA <= '0';
LEDCode <= "00000";
end case;
end process output_logic;
end Behavioral;
Datapath:
entity Datapath is
Port (BTNClock : in STD_LOGIC;
clock : in STD_LOGIC;
UncondBranch : in STD_LOGIC;
CondBranch : in STD_LOGIC;
RRtwoSelect : in STD_LOGIC;
RegWriteSelect : in STD_LOGIC;
ALUSource : in STD_LOGIC;
ALUOpCode : in STD_LOGIC_VECTOR(1 downto 0);
WriteSelect : in STD_LOGIC;
MemWrite : in STD_LOGIC;
REGCEA : in STD_LOGIC;
PCWrite : in STD_LOGIC;
seg_select : out STD_LOGIC_vector(6 downto 0);
anode_select : out STD_LOGIC_vector(7 downto 0);
ins_out : out STD_LOGIC_VECTOR(31 downto 0);
RAMSelect : in STD_LOGIC;
ALUEleven : out STD_LOGIC;
REGEleven : out STD_LOGIC;
SwitchReset : in STD_LOGIC);
end Datapath;
architecture Behavioral of Datapath is
signal PC : STD_LOGIC_VECTOR(9 downto 0);
signal instruction : STD_LOGIC_VECTOR(31 downto 0);
signal BranchSelect : STD_LOGIC;
signal ZeroBranch : STD_LOGIC;
signal RRtwo : STD_LOGIC_VECTOR(4 downto 0);
signal RegDataOut1 : STD_LOGIC_VECTOR(63 downto 0);
signal RegDataOut2 : STD_LOGIC_VECTOR(63 downto 0);
signal ALUMuxOut : STD_LOGIC_VECTOR(63 downto 0);
signal SignExtendOut : STD_LOGIC_VECTOR(63 downto 0);
signal BranchExtend : STD_LOGIC_VECTOR(9 downto 0);
signal ALUOut : STD_LOGIC_VECTOR(63 downto 0);
signal ALUZero : STD_LOGIC;
signal MemoryOut : STD_LOGIC_VECTOR(63 downto 0);
signal WriteMuxOut : STD_LOGIC_VECTOR(63 downto 0);
signal Branch : STD_LOGIC_VECTOR(9 downto 0);
signal PCNext : STD_LOGIC_VECTOR(9 downto 0);
signal PCIncrement : STD_LOGIC_VECTOR(9 downto 0);
signal ALUCommand : STD_LOGIC_VECTOR(3 downto 0);
signal InstEn : STD_LOGIC := '1';
signal OnlySeven : STD_LOGIC_VECTOR(0 downto 0);
signal SevSegReset : STD_LOGIC := '0';
begin
OnlySeven(0) <= MemWrite and not ALUOut(11);
BranchSelect <= UncondBranch or ZeroBranch;
ZeroBranch <= CondBranch and ALUZero;
ins_out <= instruction;
ALUEleven <= ALUout(11);
REGEleven <= RegDataOut1(11);
--Program Counter
PCReg : PCounter port map ( clk => BTNClock,
wea => PCWrite,
newaddress => PCNext,
thisaddress => PC);
--Incremental adder
IncAddr : B_adder port map ( a => PC,
x => PCIncrement);
--Branch Adder
BranchAddr : In_adder port map ( a => PC,
b => BranchExtend,
x => Branch);
--Next Instruction Address Mux
NextPCMux : nine_mux port map ( s => BranchSelect,
in1 => PCIncrement,
in2 => Branch,
output => PCNext);
--Additional Datapath Elements Here
end Behavioral;
Program Counter:
entity PCounter is
Port ( clk : in STD_LOGIC; --clock
wea : in STD_LOGIC; --write enable
newaddress : in STD_LOGIC_VECTOR (9 downto 0); --new address coming in
thisaddress : out STD_LOGIC_VECTOR (9 downto 0) --current address to be executed
);
end PCounter;
architecture Behavioral of PCounter is
signal reg: std_logic_vector(9 downto 0); --internal register storage
begin
process(clk) --nothing happens if this register isn't selected
begin
if clk'EVENT and clk = '1' then
thisaddress <= reg; --send out currently saved address
if wea = '1' then
reg <= newaddress; --and set register to next address
end if;
else
reg <= reg; --otherwise, maintain current value
end if;
end process;
end Behavioral;
This adder just adds one to the value currently in the PC:
entity B_adder is
Port ( a : in STD_LOGIC_VECTOR (9 downto 0);
x : out STD_LOGIC_VECTOR (9 downto 0));
end B_adder;
architecture Behavioral of B_adder is
begin
x <= a + 1;
end Behavioral;
This little mux will select if the next address is coming from the branch adder (not included here) or from the incremental adder above:
entity nine_mux is
Port ( s : in STD_LOGIC;
in1 : in STD_LOGIC_VECTOR (9 downto 0);
in2 : in STD_LOGIC_VECTOR (9 downto 0);
output : out STD_LOGIC_VECTOR (9 downto 0));
end nine_mux;
architecture Behavioral of nine_mux is
begin
with s select
output <= in1 when '0',
in2 when others;
end Behavioral;
And this is how the control unit is mapped to the datapath:
entity WholeThing is
Port ( BTNClock : in STD_LOGIC;
BTNReset : in STD_LOGIC;
SwitchReset : in STD_LOGIC;
clock : in STD_Logic;
LEDs : out STD_LOGIC_VECTOR(4 downto 0);
seg : out STD_LOGIC_vector(6 downto 0);
an : out STD_LOGIC_vector(7 downto 0);
alu11 : out STD_LOGIC;
reg11 : out STD_LOGIC
);
end WholeThing;
architecture Behavioral of WholeThing is
signal instruction : STD_LOGIC_VECTOR(31 downto 0);
signal Reg2Loc : STD_LOGIC;
signal ALUSRC : std_logic;
signal MemtoReg : std_logic;
signal RegWrite : std_logic;
signal Branch : std_logic;
signal ALUOp : std_logic_vector (1 downto 0);
signal UnconB : std_logic;
signal en : std_logic;
signal wea : std_logic;
signal PCWrite : std_logic;
signal REGCEA : std_logic;
signal SwRst : STD_LOGIC;
begin
--SwitchReset <= SwRst;
--Control Unit
CU : Fred port map ( Inst => instruction(31 downto 21),
clk => BTNClock,
rst => BTNReset,
Reg2Loc => Reg2Loc,
ALUSRC => ALUSRC,
MemtoReg => MemtoReg,
RegWrite =>RegWrite,
Branch => Branch,
ALUOp => ALUOp,
UnconB => UnconB,
en => en,
wea => wea,
PCWrite => PCWrite,
REGCEA => REGCEA,
LEDCode => LEDs);
--Datapath
DP : Datapath port map (BTNClock => BTNClock,
clock => clock,
UncondBranch => UnconB,
CondBranch => Branch,
RRtwoSelect => Reg2Loc,
RegWriteSelect => RegWrite,
ALUSource => ALUSRC,
ALUOpCode => ALUOp,
WriteSelect => MemtoReg,
MemWrite => wea,
REGCEA => REGCEA,
PCWrite => PCWrite,
seg_select => seg,
anode_select => an,
ins_out => instruction,
RAMSelect => en,
ALUEleven => alu11,
REGEleven => reg11,
SwitchReset => SwitchReset
);
end Behavioral;
The FSM - the main problem
Your second process should implement default assignments to spare lots of unnecessary else branches where you define self-edged of your FSM graph. Because you missed that, your FSM creates additional latches for signal current_state! Check your synthesis report for latch warning and you might find multiple of them.
Other mistakes in the same file
You mixed up current_state and next_state. The meaning of the signals does not
reflect your code! Your case statement needs to switch on current_state.
Don't use the 3-process pattern to describe an FSM. This is a nightmare of code
readability and maintenance! One one can read and verify the behavior of this FSM form.
You're using the attribute enum_encoding in a wrong way:
to define an FSM encoding, apply fsm_encoding to the state signal
to define a user-defined encoding apply fsm_encoding with value user to your state signal and apply enum_encoding with a space separated list of binary values to your state type.
Don't use asynchronous reset. Synchronous, clocked processes have only one signal in the sensitivity list!
Combinational processes need to list all read signals in there sensitivity list!
You shouldn't use clk'EVENT and clk = '1'. Use rising_edge(clk) instead.
If you switch on the same signal multiple times, use a case statement, but no if-elsif construct!
Your eyes and probably also your LEDs will not be fast enough to see and display LEDCode.
Corrected code:
architecture Behavioral of Fred is
attribute fsm_encoding : string;
type type_fstate is (
Fetch, L_S_D, L_S_E, L_Mem, S_Mem,
L_WB, R_I_D, I_E, R_E, I_WB, R_WB, B_E, CBZ_D, B_WB, CBZ_E,
CBZ_WB);
signal current_state : type_fstate := Fetch;
signal next_state : type_fstate;
attribute fsm_encoding of current_state : signal is "one-hot";
begin
clockprocess : process(clk)
begin
if rising_edge(clk) then
if rst = '1' then
current_state <= Fetch;
else
current_state <= next_state;
end if;
end if;
end process;
state_logic: process (current_state, Inst)
begin
next_state <= current_state;
Reg2Loc <= '0';
ALUSRC <= '0';
MemtoReg <= '0';
RegWrite <= '0';
Branch <= '0';
ALUOp <= "00";
UnconB <= '0';
en <= '0';
wea <= '0';
PCWrite <= '0';
REGCEA <= '0';
LEDCode <= "00000";
case current_state is
when Fetch => --00001
REGCEA <= '1';
LEDCode <= "00001";
case Inst is
when "11111000010" => --LDUR
next_state <= L_S_D;
when "11111000000" => --STUR
next_state <= L_S_D;
--Additional State Logic Here
when others =>
next_state <= Fetch;
end case;
when L_S_D => --00010
Reg2Loc <= '1';
LEDCode <= "00010";
next_state <= L_S_E;
when L_S_E => --00011
Reg2Loc <= '1';
ALUSRC <= '1';
PCWrite <= '1';
LEDCode <= "00011";
case Inst is
when "11111000010" =>
next_state <= L_Mem;
when "11111000000" =>
next_state <= S_Mem;
when others =>
-- ???
end case;
when S_Mem => --00110
Reg2Loc <= '1';
ALUSRC <= '1';
en <= '1';
wea <= '1';
LEDCode <= "00110";
next_state <= Fetch;
--Additional States Here
when others =>
next_state <= Fetch;
end case;
end process;
end architecture;
Mistakes in the PC:
Never assign something like this reg <= reg in VHDL!
You're using arithmetic on type std_logic_vector. This operation is:
not defined for that type, or
you're using a non IEEE package like synopsys.std_logic_unsigned, which shouldn't be used at all. Use package ieee.numeric_std and types signed/unsigned if you need arithmetic operations.
Your program counter (PC) does not count (yet?). Based on the single responsibility principle, your PC should be able to:
load a new instruction pointer
increment an instruction pointer
output the current instruction pointer
Your PC assigns the output thisaddress with one cycle of delay. Normally, this will break any CPU functionality ...
As you're going to implement your design on an FPGA device, make sure to initialize all signals that are translated to memory (e.g. registers) with appropriate init values.
Improved Code:
architecture Behavioral of PCounter is
signal reg: unsigned(9 downto 0) := (others => '0');
begin
process(clk)
begin
if rising_edge(clk) then
if wea = '1' then
reg <= unsigned(newaddress);
end if;
end if;
end process;
thisaddress <= reg;
end architecture;
Your adder B_adder
Is is wise to implement a one-line in an entity consuming 9 lines of code?
Moreover, your code is describing an incrementer, but not an adder.
Describing a Multiplexer
A Multiplexer is not described with a with ... select statement. This will create a priority logic like a chain of if-elseif branches.
output <= in1 when (s = '0') else in2;
As this is now a size independent one-liner, screw the nine_mux entity.

Create "Init" and "End" SIGNAL for module in VHDL

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity struture_test is
Port ( clk : in STD_LOGIC;
rst : in STD_LOGIC;
Init : in STD_LOGIC;
i_ia : in STD_LOGIC_VECTOR (11 downto 0);
i_ib : in STD_LOGIC_VECTOR (11 downto 0);
end_s : out std_logic;
result : out STD_LOGIC_VECTOR (11 downto 0));
end struture_test;
architecture Behavioral of struture_test is
signal en_sn : std_logic := '0';
begin
PROCESS (clk,rst)
variable acc : signed (23 downto 0) ;
variable x : signed (35 downto 0) ;
begin
if (rst = '0') then
result <= (others => '0');
end_s <= '0';
elsif (rising_edge (clk)) then
if ((Init) = '1') then
acc := signed (i_ia)*signed (i_ib);
x := acc * signed (i_ia);
result <= std_logic_vector (x(23 downto 12));
end_s <= '1';
else
end_s <= '0';
end if;
end if;
end process;
end Behavioral;
Hi everyone
I have a project which includes some blocks. The blocks link each other through Init or End Signal. It means that The End signal of one Block is connected to Init signal of the following block.
I'm confused about that Does the above code make a good Init and a End signal ?
If I change my code and convert it into Pipelined structure to operate with the higher frequency clock. The variables convert into the signals
PROCESS (clk,rst)
signal acc : signed (23 downto 0) ;
signal x : signed (35 downto 0) ;
begin
if (rst = '0') then
result <= (others => '0');
end_s <= '0';
elsif (rising_edge (clk)) then
if ((Init) = '1') then
acc <= signed (i_ia)*signed (i_ib);
x <= acc * signed (i_ia);
result <= std_logic_vector (x(23 downto 12));
end_s <= '1';
else
end_s <= '0';
end if;
end if;
end process;
How to create Init and End signal in this case? The block illustrates in the picture
The idea is good, but the code is wrong. In addition it has some bad coding smells.
Basic rules:
Do not use asynchronous resets.
You can not declare signals in processes. Process allow variable declarations; architectures allow signal declarations.
Each signal assignment in a clock process creates a flip-flop / delay of one clock cycle. So it's 3 clock cycles delay in total, but you end signal is only delayed by one cycle.
Do not enable pipelined operations. Use a delayed chain of valid bits.
Do not reset pipeline results, because underlying hardware resources like DSP (multiplication) units do not support resets.
Changed code:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity struture_test is
port (
clk : in std_logic;
rst : in std_logic;
Init : in std_logic;
i_ia : in std_logic_vector(11 downto 0);
i_ib : in std_logic_vector(11 downto 0);
end_s : out std_logic;
result : out std_logic_vector(11 downto 0) := (others => '0');
);
end entity;
architecture rtl of struture_test is
signal ValidChain : std_logic_value(2 downto 0) := (others => '0');
signal ia_delayed : signed(i_ia'range) := (others => '0');
signal acc : signed(23 downto 0) := (others => '0');
signal x : signed(35 downto 0) := (others => '0');
begin
process(clk)
begin
if rising_edge(clk) then
ValidChain <= ValidChain(ValidChain'high - 1 downto ValidChain'low) & Init;
acc <= signed(i_ia) * signed(i_ib);
ia_delayed <= signed(i_ia);
x <= acc * ia_delayed;
result <= std_logic_vector(x(23 downto 12));
end if;
end process;
end_s <= ValidChain(ValidChain'high);
end architecture;
Please note: Signal i_ia used in the 2nd multiplication needs to be delayed by one cycle, otherwise you would mix ia values from different pipeline cycles.

VHDL - My code is synthesizable and works the way i want on simulation, but it doesn't on the fpga

My VHDL-Code is functionaly correct, in simulation it does what it's thought for. I tested in many variations and the code works correct.
But when i program the fpga (Nexyx 4 ddr) everything works well except the preload of the counter.
I don't know if the load enable (load_e) output from the fsm doesn't reach the counter or if the output signal that sais the counter is loaded (counter_loaded) doesn't reach the fsm but when i program the fpga it never pases from state C or D (waiting for counter loaded) to state E or F (where it makes a countdown).
I tested the other parts of the code in the target and it works properly, so the only problema so far is that one and i can't find the error, i'm thinking about timming, but i have no idea of how to solve it.
I leave here the counter and fsm code, as well as the TOP code, i`m new in VHDL and it might be lots of bad practice mistakes.
I'm spanish, that's the reason of my bad English and also the spanish name of some signal, but i add a comment next to them.
--------COUNTER---------------------------------------
entity counter is
Generic (NBITS : positive := 15
);
Port (clk : in STD_LOGIC;
rst : in STD_LOGIC;
ce : in STD_LOGIC;
load : in STD_LOGIC_VECTOR (NBITS-1 downto 0);
load_e : in STD_LOGIC;
unit : out STD_LOGIC_VECTOR(3 downto 0);
dec : out STD_LOGIC_VECTOR(3 downto 0);
zero_n : out STD_LOGIC; --true si cuenta = 0
loaded : out STD_LOGIC);
end counter;
architecture Behavioral of counter is
signal q_i : unsigned (NBITS-1 downto 0) := (others => '1');
begin
process(clk,rst)
begin
if rst = '1' then
q_i <= (OTHERS => '1');
loaded <= '0';
elsif rising_edge(clk) then
if CE = '1' then
if load_e = '1' then --ONE OF MY GUESSES OF THE PROBLEM
q_i <= unsigned(load);
loaded <= '1';
else
q_i <= q_i - 1;
loaded <= '0';
end if;
end if;
end if;
end process;
dec <= std_logic_vector(to_unsigned((to_integer(q_i(14 downto 10)) / 10),dec'length)); --first 5 bits are the tens
unit <= std_logic_vector(to_unsigned((to_integer(q_i(14 downto 10)) rem 10),unit'length)); --fist 5 bits are the unit
zero_n <= '1' WHEN q_i < "000010000000000" ELSE '0'; --cout is zero if the first 5 bits are less tan 1 in binary
end Behavioral;
------FINITE STATE MACHINE--------------------------------
entity maquina_estados is
Port (
clk : in STD_LOGIC;
rst : in STD_LOGIC;
corto : in STD_LOGIC;
largo : in STD_LOGIC;
b_on : in STD_LOGIC;
zero_n : in STD_LOGIC;
counter_loaded : in STD_LOGIC;
load_e : out STD_LOGIC;
load : out STD_LOGIC_VECTOR(14 downto 0);
bomba_led : out STD_LOGIC;
indica_on : out STD_LOGIC);
end maquina_estados;
architecture Behavioral of maquina_estados is
type state_type is (A, B, C, D, E, F); --define state(A = powered off, B = powered on, C = short coffee preload, D = large coffee preload, E = short coffee, F = large coffee)
signal state, next_state : state_type; --type state signal
begin
process(clk,rst)
begin
if rst = '1' then
state <= A;
elsif rising_edge(clk) then
state <= next_state;
end if;
end process;
process(state, b_on, corto, largo, zero_n, counter_loaded)
begin
CASE state IS
WHEN A => if b_on = '1' then
next_state <= B;
else
next_state <= A;
end if;
WHEN B => if b_on = '0' then
next_state <= A;
elsif corto = '1' then
next_state <= C;
elsif largo = '1' then
next_state <= D;
else
next_state <= B;
end if;
WHEN C => if counter_loaded = '1' then
next_state <= E;
else
next_state <= C;
end if;
WHEN D => if counter_loaded = '1' then
next_state <= F;
else
next_state <= D;
end if;
WHEN E => if zero_n = '1' then
next_state <= B;
else
next_state <= E;
end if;
WHEN F => if zero_n = '1' then
next_state <= B;
else
next_state <= F;
end if;
WHEN OTHERS => next_state <= A;
end case;
end process;
process(state)
begin
CASE state IS
WHEN A => load <= "111111111111111"; --default value of the count
load_e <= '0';
bomba_led <= '0';
indica_on <= '0';
WHEN B => load <= "111111111111111";
load_e <= '0';
bomba_led <= '0';
indica_on <= '1';
WHEN C => load <= "010101111111111"; --10 second, this in addition to a 1024 hz clock made posible to use the first 5 bits as the number
load_e <= '1';
bomba_led <= '0';
indica_on <= '1';
WHEN D => load <= "101001111111111"; --20 seconds
load_e <= '1';
bomba_led <= '0';
indica_on <= '1';
WHEN E => load <= "111111111111111";
load_e <= '0';
bomba_led <= '1';
indica_on <= '1';
WHEN F => load <= "111111111111111";
load_e <= '0';
bomba_led <= '1';
indica_on <= '1';
end case;
end process;
end behavioral;
------TOP-----------------------
entity TOP is
Generic(
FIN : positive := 100000000;
FOUT : positive := 1024);
Port ( clk : in STD_LOGIC;
rst : in STD_LOGIC;
corto : in STD_LOGIC;
largo : in STD_LOGIC;
b_on : in STD_LOGIC;
display_number : out STD_LOGIC_VECTOR (6 downto 0);
display_selection : out STD_LOGIC_VECTOR (7 downto 0);
bomba_led : out STD_LOGIC;
indica_on : out STD_LOGIC);
end TOP;
architecture Behavioral of TOP is
--instancies
component clk_divider is
-- Port ( );
generic(
FIN : positive;
FOUT : positive
);
port (
Clk : in STD_LOGIC;
Reset : in STD_LOGIC;
Clk_out : out STD_LOGIC
);
end component;
component maquina_estados is
Port ( clk : in STD_LOGIC;
rst : in STD_LOGIC;
corto : in STD_LOGIC;
largo : in STD_LOGIC;
b_on : in STD_LOGIC;
zero_n : in STD_LOGIC;
counter_loaded : in STD_LOGIC;
load_e : out STD_LOGIC;
load : out STD_LOGIC_VECTOR(14 downto 0);
bomba_led : out STD_LOGIC;
indica_on : out STD_LOGIC);
end component;
component counter is
Generic (NBITS : positive
);
Port (clk : in STD_LOGIC;
rst : in STD_LOGIC;
ce : in STD_LOGIC;
load : in STD_LOGIC_VECTOR (NBITS-1 downto 0);
load_e : in STD_LOGIC;
unit : out STD_LOGIC_VECTOR(3 downto 0);
dec : out STD_LOGIC_VECTOR(3 downto 0);
zero_n : out STD_LOGIC;
loaded : out STD_LOGIC);
end component;
component clk_manager is
generic(
CLK_FREQ : positive
);
Port (
clk : in STD_LOGIC;
rst : in STD_LOGIC;
strobe_1024Hz : out STD_LOGIC;
strobe_128Hz : out STD_LOGIC
);
end component;
component decoder is
Port ( code : in STD_LOGIC_VECTOR(3 downto 0);
led : out STD_LOGIC_vector(6 downto 0)
);
end component;
component display_refresh is
Port ( clk : in STD_LOGIC;
ce : in STD_LOGIC;
segment_unit : in STD_LOGIC_VECTOR (6 downto 0);
segment_dec : in STD_LOGIC_VECTOR (6 downto 0);
display_number : out STD_LOGIC_VECTOR (6 downto 0);
display_selection : out STD_LOGIC_VECTOR (1 downto 0)); --cada elemento del vector corresponde a un 7 seg, true se ve false no
end component;
-- prescaler signals
signal prescaler_clk_out : STD_LOGIC;
--maquina estados signals
signal zero_n_fsm : STD_LOGIC;
signal load_e_fsm : STD_LOGIC;
signal load_fsm : STD_LOGIC_VECTOR(14 downto 0);
signal bomba_led_fsm: STD_LOGIC;
--counter signals
signal unit : STD_LOGIC_VECTOR(3 downto 0);
signal dec : STD_LOGIC_VECTOR(3 downto 0);
signal zero_n_cntr : STD_LOGIC;
signal load_e_cntr : STD_LOGIC;
signal load_cntr : STD_LOGIC_VECTOR(14 downto 0);
signal counter_loaded : STD_LOGIC;
--clk_manager signals
signal strobe_1024Hz : STD_LOGIC;
signal strobe_128Hz : STD_LOGIC;
signal ce_clkm : STD_LOGIC;
signal rst_clkm : STD_LOGIC;
--decoders signals
signal unit_code : STD_LOGIC_VECTOR(6 downto 0);
signal dec_code : STD_LOGIC_VECTOR(6 downto 0);
--display refresh signals
signal display_refresh_number : STD_LOGIC_VECTOR(6 downto 0);
signal display_refresh_selection : STD_LOGIC_VECTOR(1 downto 0);
begin
prescaler: clk_divider
generic map(
FIN => FIN,
FOUT => FOUT
)
port map(
Clk => clk,
Reset => rst,
Clk_out => prescaler_clk_out
);
sm: maquina_estados
Port map( clk => prescaler_clk_out,
rst => rst,
corto => corto,
largo => largo,
b_on => b_on,
zero_n => zero_n_fsm,
counter_loaded => counter_loaded,
load_e => load_e_fsm,
load => load_fsm,
bomba_led => bomba_led_fsm,
indica_on => indica_on);
cntr: counter
Generic map(NBITS => 15
)
Port map(clk => clk,
rst => rst,
ce => strobe_1024Hz,
load => load_cntr,
load_e => load_e_fsm,
unit => unit,
dec => dec,
zero_n => zero_n_cntr,
loaded => counter_loaded);
clk_m: clk_manager
generic map(
CLK_FREQ => FIN
)
Port map(
clk => clk,
rst => rst,
strobe_1024Hz => strobe_1024Hz,
strobe_128Hz => strobe_128Hz
);
unit_dcd: decoder
Port map(
code => unit,
led => unit_code
);
dec_dcd: decoder
Port map(
code => dec,
led => dec_code
);
dr: display_refresh
Port map(
clk => clk,
ce => strobe_128Hz,
segment_unit => unit_code,
segment_dec => dec_code,
display_number => display_refresh_number,
display_selection => display_refresh_selection);
display_number <= display_refresh_number WHEN bomba_led_fsm = '1' ELSE "1111111";
display_selection <= ("111111" & display_refresh_selection) WHEN bomba_led_fsm = '1' ELSE "11111111";
zero_n_fsm <= zero_n_cntr;
bomba_led <= bomba_led_fsm;
load_cntr <= load_fsm;
end Behavioral;
Here are all the reports that the implementation ans sythesis gave me:
Synthesis reports
implementation reports 1/6
implementation reports 2/6
implementation reports 3/6
implementation reports 4/6
implementation reports 5/6
implementation reports 6/6
I hope someone could find the problema and give me a solution or a way of how to debug this problem.
Thanks.
Your FSM is clocked on prescaler_clk_out, and your counter is clocked on clk, which is a red flag. This could easily lead to an implementation failure.
Draw a timing diagram showing all your clocks and resets, and your lower-frequency enables (in particular, strobe_1024Hz)
Try to clock all the logic on the same clock, presumably clk, and make sure that everything is synchronous to this clock (in other words, inputs have sufficient setup and hold times relative to this clock)
Make sure you are actually resetting the chip
Once you've done the timing diagram, write a constraints file that tells the synthesiser what your clocks are. clk_manager and clk_divider may be an issue here, but hopefully everything will be clocked on just 'clk', and the contstraints file will contain only the clock name and frequency. If you still can't get it to work, ask a new question, showing your timing diagram, and your attempt at a constraints file.

Place:1108 error in VHDL (Help)

I am designing a simple combination lock design in VHDL on a Spartan 6 FPGA. This error has come up and i am a bit confused to how i could fix it. I have "googled" this and according to this answer in this thread Too many comps of type “BUFGMUX” found to fit this deviceI beleive i know the problem but i am unsure how to solve it.
Now correct me if i am wrong but i believe this error came about due to the following code in my design
--clock divider
process(cclk,clr)
begin
if (clr ='1') then
Count200Hz <= X"00000";
--clk200 <= '0';
temp <= '0';
elsif rising_edge(cclk) then
if (Count200Hz = clk200HzEndVal) then
clk200 <= not temp;
Count200Hz <= X"00000";
else
Count200Hz <= Count200Hz + '1';
end if;
end if;
end process;
-- 2-bit counter
process(cclk,clr)
begin
if clr = '1' then
s <= "00";
elsif rising_edge(cclk) then
s <= s+1;
end if;
end process;
--state machine
state_mach:PROCESS(lclk, clr)
BEGIN
IF clr = '1' THEN
present_state <= idle;
ELSIF rising_edge(lclk) THEN
present_state <= next_state;
end if;
END PROCESS;
pulse_process: process(cclk, rst)
begin
if rst = '0' then
pulse <= '0';
count <= 0;
current_state <= idle;
elsif (rising_edge(cclk))then
current_state <= next_state;
....
These code are from different vhdl modules in my design.
does the ise believes that there are three different clock used in my design hence why the error is thrown??
The thing is that they are different clock but they stem from the systems clock ones the clock at an lower frequency, one is the clock pulse.
I have added my top-level design for some clarity
Any help is appreciated
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
entity simpleLock_top is
Port (
mclk : in STD_LOGIC;
rst : in STD_LOGIC;
btnl : in STD_LOGIC;
btnr : in STD_LOGIC;
sw : in STD_LOGIC_VECTOR (3 downto 0);
seg7 : out STD_LOGIC_VECTOR (6 downto 0);
an : out STD_LOGIC_VECTOR (3 downto 0);
led : out STD_LOGIC_VECTOR (7 DOWNTO 0);
dp : out STD_LOGIC);
end simpleLock_top;
architecture Behavioral of simpleLock_top is
component x7seg_msg is
Port (
x : in STD_LOGIC_VECTOR (15 downto 0);
cclk : in STD_LOGIC;
clr : in STD_LOGIC;
seg7 : out STD_LOGIC_VECTOR (6 downto 0);
an : out STD_LOGIC_VECTOR (3 downto 0);
dp : out STD_LOGIC);
end component;
component clkdiv is
Port (
cclk : in STD_LOGIC;
clr : in STD_LOGIC;
clk200 : out STD_LOGIC);
end component;
component simpleLock is
PORT (
lclk : IN STD_LOGIC;
clr : IN STD_LOGIC;
btnl : IN STD_LOGIC;
btnr : IN STD_LOGIC;
code : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
sw : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
led : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
digit : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
user_input : OUT STD_LOGIC_VECTOR(15 downto 0));
end component;
component clock_pulse is
PORT (
cclk : IN STD_LOGIC;
rst : IN STD_LOGIC;
trig : IN STD_LOGIC;
pulse : OUT STD_LOGIC);
end component;
constant code : STD_LOGIC_VECTOR(15 downto 0):= X"1234";
signal digit: STD_LOGIC_VECTOR(3 DOWNTO 0);
signal user_input : std_logic_vector(15 downto 0);
signal clk200, clkp, btn01: STD_LOGIC;
signal btn : STD_LOGIC_VECTOR(1 DOWNTO 0);
begin
btn(0) <= btnr;
btn(1) <= btnl;
btn01 <= btn(0) or btn(1);
--led <= X"00";
V1: clkdiv
port map(
cclk => mclk,
clr => rst,
clk200 => clk200);
V2: x7seg_msg
port map(
x => user_input,
cclk => clk200,
clr => rst,
seg7 => seg7,
an => an,
dp => dp );
V3: simpleLock
port map(
lclk => clkp,
clr => rst,
btnl => btnl,
btnr => btnr,
code => code,
sw => sw,
led => led,
digit => digit,
user_input => user_input);
V4: clock_pulse
port map(
cclk => clk200,
rst => rst,
trig => btn01,
pulse => clkp);
end Behavioral;
Clock Enable
In an FPGA design, it is often better to use the less possible different clocks.
If your "clock_pulse" module generate a one cycle clock pulse, don't use this pulse as a clock ('clkp' in your code), but as a clock enable ('enable' in the code below).
myproc : process(clk, rst)
begin
if rst = '1' THEN
-- your asynchronously reseted signals
elsif rising_edge(clk) THEN
if enable = '1' then
-- things that must be done when you get the one cycle pulse
end if;
end if;
end process;
But take care of any unmanaged clock domain crossing...
Hope this helps.

Resources