Error (10818): Can't infer register because it does not hold its value outside the clock edge, how to fix it? - vhdl

I have this code for a ram in VHDL and I get the following error while synthesis:
Error (10818): Can't infer register for "data_table[19][13]" at RAM.vhd(50) because it does not hold its value outside the clock edge
any help would be appreciated!
here is the code:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity RAM is
port (
clk, wr_en : in std_logic;
address: in std_logic_vector (9 downto 0);
data_in : in std_logic_vector (15 downto 0);
data_out: out std_logic_vector (15 downto 0)
);
end entity RAM;
architecture RAM_Arch of RAM is
type Memory is array (0 to 1023) of std_logic_vector (15 downto 0);
signal data_table : Memory := (others => (others => '0'));
begin
process (clk)
variable init : boolean := true;
begin
if init = true then
-- some initiation
data_table(0) <= "0001010000011010";
data_table(1) <= "0011110000001000";
data_table(2) <= "0011110000010000";
data_table(3) <= "0011110000100000";
data_table(4) <= "0011110000000001";
data_table(10) <= "0001010000011100";
data_table(11) <= "0100000000000001";
data_table(12) <= "0011110000000001";
data_table(13) <= "0011110000000010";
data_table(14) <= "0011110000000100";
data_table(15) <= "0011110000001000";
data_table(16) <= "0011110000010000";
data_table(17) <= "0011110000100000";
-- data_table(18) <= "0011110001000000";
data_table(19) <= "1011110000010000";
-- data_table(19) <= "1011110000000001";
-- data_table(20) <= "1011110000000010";
-- data_table(21) <= "1011110000000100";
-- data_table(22) <= "1011110000001000";
-- data_table(24) <= "1011110000100000";
-- data_table(25) <= "1011110001000000";
-- data_table(26) <= "1011110010000000";
init := false;
end if;
if clk'event and clk = '1' then
if wr_en = '1' then -- Writing :)
data_table(to_integer(unsigned(address))) <= data_in;
end if;
end if;
end process;
data_out <= data_table(to_integer(unsigned(address)));
end architecture RAM_Arch;

If your code must be synthesized never put non-synchronous assignments in a synchronous process. Try:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity ram is
port (
clk, wr_en: in std_logic;
address: in std_logic_vector(9 downto 0);
data_in : in std_logic_vector(15 downto 0);
data_out: out std_logic_vector(15 downto 0)
);
end entity ram;
architecture ram_arch of ram is
type memory is array (0 to 1023) of std_logic_vector (15 downto 0);
signal data_table: memory := (
0 => "0001010000011010",
1 => "0011110000001000",
2 => "0011110000010000",
3 => "0011110000100000",
4 => "0011110000000001",
10 => "0001010000011100",
11 => "0100000000000001",
12 => "0011110000000001",
13 => "0011110000000010",
14 => "0011110000000100",
15 => "0011110000001000",
16 => "0011110000010000",
17 => "0011110000100000",
-- 18 => "0011110001000000",
19 => "1011110000010000",
-- 19 => "1011110000000001",
-- 20 => "1011110000000010",
-- 21 => "1011110000000100",
-- 22 => "1011110000001000",
-- 24 => "1011110000100000",
-- 25 => "1011110001000000",
-- 26 => "1011110010000000",
others => (others => '0'));
begin
process (clk)
begin
if rising_edge(clk) then
if wr_en = '1' then -- writing :)
data_table(to_integer(unsigned(address))) <= data_in;
end if;
end if;
end process;
data_out <= data_table(to_integer(unsigned(address)));
end architecture ram_arch;
Note: you should probably not use std_logic. If you do not know the difference with std_ulogic prefer the latter. Same with std_logic_vector: prefer std_ulogic_vector.

Related

Modelsim Altera VHDL MEMORY ROM

I am confused on to why my VHDL design is not working. I am to create a top.vhd file that will program an FPGA board to display addresses 0 through 15 and the corresponding values to each address. When I simulate my design, all the clocks and resets work. The problem I am having is my FSM processes and Address process. I know there is a lot going on here, so if you need clarification I can answer your questions.
library IEEE;
use IEEE.std_logic_1164.ALL;
use IEEE.numeric_std.all;
entity top is
port(Clock : in std_logic;
Reset : in std_logic;
SW : in std_logic_vector (1 downto 0);
HEX2, HEX4: out std_logic_vector ( 6 downto 0);
KEY0: in std_logic);
end entity;
architecture top_arch of top is
component char_decoder is
port(BIN_IN : in std_logic_vector (3 downto 0);
HEX_OUT : out std_logic_vector (6 downto 0));
end component;
component rom_16x4_sync is
port (clock: in std_logic;
address: in std_logic_vector (3 downto 0);
rom_en: in std_logic;
data_out: out std_logic_vector(3 downto 0));
end component;
type state_type is (start, read_rom, clear_addr, done);
signal current_state, next_state : state_type;
signal Rom_en, addr_count_clr, addr_count_en : std_logic;
signal address_counter : integer range 0 to 15;
signal address_uns : unsigned (3 downto 0);
signal clock_slow : std_logic;
signal rom_out : std_logic_vector (3 downto 0);
begin
char : char_decoder port map (BIN_IN => rom_out, HEX_OUT => HEX2);
char1 : char_decoder port map (BIN_IN => std_logic_vector(address_uns), HEX_OUT => HEX4);
clock_slow <= Clock;
rom : rom_16x4_sync port map (clock => clock_slow, address => std_logic_vector(address_uns), rom_en => Rom_en, data_out => rom_out);
State_Memory : process (clock_slow, Reset)
begin
if (Reset = '0') then
current_state <= start;
elsif (clock_slow'event and clock_slow = '1') then
current_state <= next_state;
end if;
end process;
NEXT_STATE_LOGIC : process (current_state)
begin
case (current_state) is
when start => if (KEY0 = '0') then
next_state <= read_rom;
else next_state <= start;
end if;
when read_rom => if (address_counter = 15) then
next_state <= clear_addr;
else
address_counter <= address_counter + 1;
end if;
when clear_addr => next_state <= done;
address_counter <= 0;
when done => next_state <= done;
end case;
end process;
OUTPUT_LOGIC : process (current_state)
begin
case (current_state) is
when start => Rom_en <= '0';
addr_count_en <= '0';
addr_count_clr <= '0';
when read_rom => Rom_en <= '1';
addr_count_en <= '1';
addr_count_clr <= '0';
when clear_addr => Rom_en <= '0';
addr_count_en <= '1';
addr_count_clr <= '1';
when done => Rom_en <= '0';
addr_count_en <= '0';
addr_count_clr <= '0';
end case;
end process;
Address_Count : process (addr_count_en, addr_count_clr, clock_slow)
begin
if (clock_slow'event and clock_slow = '1') then
if (addr_count_en = '1') then
if (addr_count_clr = '1') then
address_uns <= "0000";
else
address_uns <= address_uns + 1;
end if;
end if;
end if;
end process;
address_uns <= to_unsigned(address_counter,4);
end architecture;
I commented on what I could see wrong with your code:
address_counter isn't clocked and is redundant. Remove the assignments and change the comparison to address_uns (which should also go into the sensitivity list) in process NEXT_STATE_LOGIC. Remove the concurrent signal assignment to address_uns following process Address_Counter. If processes Address_Count and OUTPUT_LOGIC are correct as well as rom_16x4_sync you should have something that works.
Well I had most the bits and pieces sitting around from other questions to gen a complete MCVE together with little effort mostly by copying and pasting and that gave:
As you can see that didn't work, and the reason why is that address_uns needs to be reset (it's default value is all 'U's).
Adding a reset gives:
So the gist of this is that your state machine was almost correct, it was missing the address counter in it's sensitivity list and had two address counters. Limiting that to one and resetting it so you weren't adding 1 to all 'U's shows your state machine is working.
And the code with all the fixes:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity char_decoder is
port (
bin_in: in std_logic_vector (3 downto 0);
hex_out: out std_logic_vector (6 downto 0)
);
end entity;
architecture dummy of char_decoder is
-- seven segment display
--
-- a
-- f b
-- g
-- e c
-- d
--
-- SEGMENT is defined (g downto a)
--
type segment7 is array (integer range 0 to 15) of
std_logic_vector (6 downto 0);
constant hex_to_segment: segment7 := (
"1000000", -- 0
"1111001", -- 1
"0100100", -- 2
"0110000", -- 3
"0011001", -- 4
"0010010", -- 5
"0000010", -- 6
"1111000", -- 7
"0000000", -- 8
"0011000", -- 9
"0001000", -- A
"0000011", -- b
"0111001", -- C
"0100001", -- d
"0000110", -- E
"0001110" -- F
);
begin
process (bin_in)
variable seg7_val: integer range 0 to 15;
begin
seg7_val := to_integer(unsigned(bin_in));
hex_out <= hex_to_segment(seg7_val);
end process;
end architecture;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity rom_16x4_sync is
port (
clock: in std_logic;
address: in std_logic_vector (3 downto 0);
rom_en: in std_logic;
data_out: out std_logic_vector(3 downto 0)
);
end entity;
architecture dummy of rom_16x4_sync is
type rom_array is array (0 to 15) of std_logic_vector(3 downto 0);
function fill_rom return rom_array is
variable ret_val: rom_array;
begin
for i in rom_array'reverse_range loop -- backward to i
ret_val(i) := std_logic_vector(to_unsigned(i,4));
end loop;
return ret_val;
end function;
constant rom: rom_array := fill_rom;
begin
process (clock)
begin
if rising_edge(clock) and rom_en = '1' then -- NO RESET
data_out <= rom(to_integer(unsigned(address)));
end if;
end process;
end architecture;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity top is
port (
clock: in std_logic;
reset: in std_logic;
sw: in std_logic_vector (1 downto 0); -- not used?
hex2, hex4: out std_logic_vector ( 6 downto 0);
key0: in std_logic
);
end entity;
architecture top_arch of top is
component char_decoder is
port (
bin_in: in std_logic_vector (3 downto 0);
hex_out: out std_logic_vector (6 downto 0)
);
end component;
component rom_16x4_sync is
port (
clock: in std_logic;
address: in std_logic_vector (3 downto 0);
rom_en: in std_logic;
data_out: out std_logic_vector(3 downto 0)
);
end component;
type state_type is (start, read_rom, clear_addr, done);
signal current_state,
next_state: state_type;
signal rom_en,
addr_count_clr,
addr_count_en: std_logic;
-- signal address_counter: integer range 0 to 15;
signal address_uns: unsigned (3 downto 0);
signal clock_slow: std_logic;
signal rom_out: std_logic_vector (3 downto 0);
begin
char:
char_decoder
port map (
bin_in => rom_out,
hex_out => hex2
);
char1:
char_decoder
port map (
bin_in => std_logic_vector(address_uns),
hex_out => hex4
);
clock_slow <= clock;
rom:
rom_16x4_sync
port map (
clock => clock_slow,
address => std_logic_vector(address_uns),
rom_en => rom_en, data_out => rom_out
);
state_memory:
process (clock_slow, reset)
begin
if reset = '0' then
current_state <= start;
elsif clock_slow'event and clock_slow = '1' then
current_state <= next_state;
end if;
end process;
next_state_logic:
-- process (current_state)
process (current_state, address_uns)
begin
case (current_state) is
when start =>
if key0 = '0' then
next_state <= read_rom;
else
next_state <= start;
end if;
when read_rom =>
if address_uns = 15 then
next_state <= clear_addr;
-- else
-- address_counter <= address_counter + 1;
end if;
when clear_addr => -- not a defined sequential logic inference
next_state <= done;
-- address_counter <= 0;
when done =>
next_state <= done;
end case;
end process;
output_logic:
process (current_state)
begin
case (current_state) is
when start =>
rom_en <= '0';
addr_count_en <= '0';
addr_count_clr <= '0';
when read_rom =>
rom_en <= '1';
addr_count_en <= '1';
addr_count_clr <= '0';
when clear_addr =>
rom_en <= '0';
addr_count_en <= '1';
addr_count_clr <= '1';
when done =>
rom_en <= '0';
addr_count_en <= '0';
addr_count_clr <= '0';
end case;
end process;
address_count:
process (addr_count_en, addr_count_clr, clock_slow)
begin
if reset = '0' then -- added reset
address_uns <= (others =>'0');
elsif clock_slow'event and clock_slow = '1' then
if addr_count_en = '1' then
if addr_count_clr = '1' then
address_uns <= "0000";
else
address_uns <= address_uns + 1;
end if;
end if;
end if;
end process;
-- address_uns <= to_unsigned(address_counter, 4);
end architecture;
library ieee;
use ieee.std_logic_1164.all;
entity top_tb is
end entity;
architecture foo of top_tb is
signal clock: std_logic := '0';
signal reset: std_logic := '1';
signal sw: std_logic_vector (1 downto 0) := "00";
signal hex2, hex4: std_logic_vector ( 6 downto 0);
signal key0: std_logic := '0';
begin
DUT:
entity work.top
port map (
clock => clock,
reset => reset,
sw => sw,
hex2 => hex2,
hex4 => hex4,
key0 => key0
);
CLK:
process
begin
wait for 5 ns;
clock <= not clock;
if now > 200 ns then
wait;
end if;
end process;
STIMULIS:
process
begin
wait for 1 ns;
reset <= '0';
wait for 10 ns;
reset <= '1';
wait for 10 ns;
wait;
end process;
end architecture;
The char_decoder I used should be fully functional. The ROM contents are simply dummied up.

ALU implementation w/ ADDER

Hello I'm trying to create a 32-bit adder with a few opcodes and I've got it working quite well except for two cases and I can't seem to find what's causing them.. Maybe you can help me?
The subtraction case always fails for some reason and the ADDC case fails to compute the correct output when it should be using the carry bit in c_reg that has been created by the ADDS operation.
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
ENTITY ALU IS
GENERIC(WIDTH : NATURAL := 32);
PORT(Clk : IN STD_LOGIC := '0';
Reset : IN STD_LOGIC := '0';
A : IN STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0) := (OTHERS => '0');
B : IN STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0) := (OTHERS => '0');
Op : IN STD_LOGIC_VECTOR(3 DOWNTO 0) := (OTHERS => '0');
Outs : OUT STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0));
END ALU;
ARCHITECTURE arch_ALU OF ALU IS
COMPONENT adder
PORT(OpA : IN STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0);
OpB : IN STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0);
Cin : IN STD_LOGIC;
Cout : OUT STD_LOGIC;
Result : OUT STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0));
END COMPONENT;
SIGNAL adder_output : STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0) := (OTHERS => '0');
SIGNAL B_neg : STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0) := (OTHERS => '0');
SIGNAL c_flag : STD_LOGIC := '0';
SIGNAL c_reg : STD_LOGIC := '0';
SIGNAL cin : STD_LOGIC := '0';
BEGIN
adder_comp : adder
PORT MAP(OpA => A,
OpB => B_neg,
Cin => cin,
Result => adder_output,
Cout => c_flag);
WITH Op SELECT
B_neg <= NOT(B) WHEN "1000",
B WHEN OTHERS;
WITH Op SELECT
cin <= '1' WHEN "1000", -- SUB
c_reg WHEN "0111", -- ADDC
'0' WHEN OTHERS; -- ADD/ADDS
ALU_Process:
PROCESS(Clk)
BEGIN
IF Reset = '0' THEN
Outs <= (OTHERS => '0');
ELSIF rising_edge(Clk) THEN
CASE Op IS
WHEN "0001" => Outs <= A AND B;
WHEN "0010" => Outs <= A OR B;
WHEN "0011" => Outs <= A NOR B;
WHEN "0100" => Outs <= A XOR B;
WHEN "0101" => Outs <= adder_output; -- ADD
WHEN "0110" => Outs <= adder_output; -- ADDS
c_reg <= c_flag;
WHEN "0111" => Outs <= adder_output; -- ADDC
WHEN "1000" => Outs <= adder_output; -- SUB
WHEN "1001" => Outs <= STD_LOGIC_VECTOR(UNSIGNED(A) SLL to_integer(UNSIGNED(B(4 DOWNTO 0))));
WHEN "1010" => Outs <= STD_LOGIC_VECTOR(unsigned(A) SRL to_integer(UNSIGNED(B(4 DOWNTO 0))));
WHEN "1011" => Outs <= STD_LOGIC_VECTOR(shift_right(SIGNED(A),to_integer(UNSIGNED(B(4 DOWNTO 0)))));
WHEN OTHERS => Outs <= (OTHERS => '0');
END CASE;
END IF;
END PROCESS;
END arch_ALU;
Only the ADDS operation should write it's carry-out to the c_reg and ADDC operation should take the c_reg into account when calculating it's output
The adder is tested and working correctly so the problem is not in the adder design.
First of all I'd like to get to know the problem of the subtraction because it is doing subtraction but the result is a little bit off.. For example:
A : h'E6A4960F
B : h'7B494E34
Op : d'1000
Outs: h'6B5B47DA while it should be h'6B5B47DB
A : h'EFDE31A3
B : h'0BCAB8FA
Op : d'1000
Out : h'E41378BB while should be h'E41378A9
Can you spot my misstake? Cause I certainly can't..
While you didn't provide a Minimal, Complete, and Verifiable example the reader can at least test the subtract portions of your design that are present:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity alu is
generic (width: natural := 32);
port (
clk: in std_logic := '0';
reset: in std_logic := '0';
a: in std_logic_vector(width - 1 downto 0) := (others => '0');
b: in std_logic_vector(width - 1 downto 0) := (others => '0');
op: in std_logic_vector(3 downto 0) := (others => '0');
outs: out std_logic_vector(width - 1 downto 0)
);
end alu;
architecture arch_alu of alu is
-- component adder
-- port (
-- opa: in std_logic_vector(width - 1 downto 0);
-- opb: in std_logic_vector(width - 1 downto 0);
-- cin: in std_logic;
-- cout: out std_logic;
-- result: out std_logic_vector(width - 1 downto 0)
-- );
-- end component;
procedure adder (
signal opa: in std_logic_vector(width - 1 downto 0);
signal opb: in std_logic_vector(width - 1 downto 0);
signal cin: in std_logic;
signal cout: out std_logic;
signal result: out std_logic_vector(width - 1 downto 0)
) is
variable sum: unsigned (width downto 0);
begin
sum := unsigned('0' & opa) + unsigned(opb) + unsigned'(""& cin);
result <= std_logic_vector(sum (width - 1 downto 0));
cout <= sum(width);
end procedure;
signal adder_output: std_logic_vector(width - 1 downto 0) := (others => '0');
signal b_neg: std_logic_vector(width - 1 downto 0) := (others => '0');
signal c_flag: std_logic := '0';
signal c_reg: std_logic := '0';
signal cin: std_logic := '0';
begin
adder_comp:
adder
-- port map (
(
opa => a,
opb => b_neg,
cin => cin,
result => adder_output,
cout => c_flag
);
with op select
b_neg <= not b when "1000",
b when others;
with op select
cin <= '1' when "1000", -- sub
c_reg when "0111", -- addc
'0' when others; -- add/adds
alu_process:
process(clk)
begin
if reset = '0' then
outs <= (others => '0');
elsif rising_edge(clk) then
case op is
when "0001" => outs <= a and b;
when "0010" => outs <= a or b;
when "0011" => outs <= a nor b;
when "0100" => outs <= a xor b;
when "0101" => outs <= adder_output; -- add
when "0110" => outs <= adder_output; -- adds
c_reg <= c_flag;
when "0111" => outs <= adder_output; -- addc
when "1000" => outs <= adder_output; -- sub
when "1001" => outs <= std_logic_vector (
unsigned(a) sll to_integer(unsigned(b(4 downto 0)))
);
when "1010" => outs <= std_logic_vector (
unsigned(a) srl to_integer(unsigned(b(4 downto 0)))
);
when "1011" => outs <= std_logic_vector (
shift_right(signed(a),to_integer(unsigned(b(4 downto 0))))
);
when others => outs <= (others => '0');
end case;
end if;
end process;
end arch_alu;
library ieee;
use ieee.std_logic_1164.all;
entity alu_tb is
end entity;
architecture foo of alu_tb is
constant width: integer := 32;
signal clk: std_logic := '0';
signal reset: std_logic := '0';
signal a: std_logic_vector(width - 1 downto 0) := (others => '0');
signal b: std_logic_vector(width - 1 downto 0) := (others => '0');
signal op: std_logic_vector(3 downto 0) := (others => '0');
signal outs: std_logic_vector(width - 1 downto 0);
begin
CLOCK:
process
begin
wait for 10 ns;
clk <= not clk;
if Now > 90 ns then
wait;
end if;
end process;
DUT:
entity work.alu
port map (
clk => clk,
reset => reset,
a => a,
b => b,
op => op,
outs => outs
);
STIMULUS:
process
begin
wait for 20 ns;
reset <= '1';
a <= x"E6A4960F";
b <= x"7B494E34";
op <= "1000";
wait for 20 ns;
a <= x"EFDE31A3";
b <= x"0BCAB8FA";
wait for 20 ns;
wait;
end process;
end architecture;
I wrote a quick and dirty procedure adder. This eliminates your adder entity/architecture and the component declaration.
I added a simple testbench for the two subtractions, this eliminates your test bench or testing procedure.
And this gives:
And as you can see the results are what you claim as correct.
So what that leaves is either your adder or your testbench (it's a stretch to blame your component declaration).
So what we get from this is that you haven't presented enough information to determine where the error is.
I did this little demonstration because the two errors don't have all the wrong bits in common. If you've tested your adder and are sure of it, it's probably the stimulus input when subtracting.

control icap in Partial Reconfiguration

I'm going to implement partial reconfiguration on virtex5 Xilinx Board. I've written 3 modules(top module and up-counter and down-counter) and created bit streams by Plan-ahead.The result is shown by 2 LEDs(up or down count). My problem is how to exchange counter partitions? or how to control icap by time or an external signal?
I prefer to don't use Microblaze so write state machine for icap as below:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_arith.ALL;
use IEEE.STD_LOGIC_unsigned.ALL;
library UNISIM;
use UNISIM.VComponents.all;
Library UNIMACRO;
use UNIMACRO.vcomponents.all;
entity Main is
port(
Clk: in std_logic;
Output: out std_logic_vector(2 downto 0)
);
end Main;
architecture Behavioral of Main is
signal Q: std_logic_vector(47 downto 0);
signal Load, Clk1hz, Clk1 : std_logic;
signal Local : std_logic_vector(1 downto 0);
component ROM ------------------------------ ROM Component Decleration
port (
Clka: in std_logic;
Addra: in std_logic_vector(11 downto 0);
Douta: out std_logic_vector(31 downto 0));
end component; -------------------------------------------------------End
signal ROM_Address, ROM_Address_Init : std_logic_vector(11 downto 0); -------- ROM and ICAP Signals Decleration
signal ROM_Data : std_logic_vector(31 downto 0);
signal ICAP_Din, ICAP_Dout : std_logic_vector(31 downto 0);
signal ICAP_CE, ICAP_Clk, ICAP_Clk1, En, ROM_Clk, ROM_Clk1, ICAP_WR : std_logic; --------------------------------------End
begin
Clk1Hz <= Clk1;
process(clk)
begin
if (rising_edge(Clk)) then
if (Q=x"000005F5E100") then
Load <= '1';
Clk1 <= not Clk1;
else
Load <= '0';
end if;
end if;
end process;
Output(0) <= not(En);
Output(2 downto 1) <= not(Local);
----------------------------------------------------
----------------------------------------------------
U_UpDown: entity work.Counter
port map(
Clk => Clk1Hz, En => '1', Output => Local
);
----------------------------------------------------
----------------------------------------------------
U1 : COUNTER_LOAD_MACRO
generic map (
COUNT_BY => X"000000000001", -- Count by value
DEVICE => "VIRTEX5", -- Target Device: "VIRTEX5", "VIRTEX6", "SPARTAN6"
WIDTH_DATA => 48) -- Counter output bus width, 1-48
port map (
Q => Q, -- Counter output, width determined by WIDTH_DATA generic
CLK => CLK, -- 1-bit clock input
CE => '1', -- 1-bit clock enable input
DIRECTION => '1', -- 1-bit up/down count direction input, high is count up
LOAD => LOAD, -- 1-bit active high load input
LOAD_DATA => x"000000000000", -- Counter load data, width determined by WIDTH_DATA generic
RST => '0' -- 1-bit active high synchronous reset
);
--------------------------------------------
--------------------------------------------
process(Clk1Hz) -------------------------------------------- ROM and ICAP Modules and Related Codes
variable Count : integer range 0 to 6:=0;
begin
if (rising_edge(Clk1Hz)) then
Count := Count + 1;
if (Count = 2) then
En <= '1';
ROM_Address_Init <= conv_std_logic_vector(0,12);
else
En <= '0';
end if;
end if;
end process;
--------------------------------------------
--------------------------------------------
U_ROM: ROM
port map (Clka => ROM_Clk1, Addra => ROM_Address, Douta => ROM_Data);
BUFG_inst : BUFG
port map (
O => ROM_Clk1, -- Clock buffer output
I => ROM_Clk -- Clock buffer input
);
BUFG_inst1 : BUFG
port map (
O => ICAP_Clk1, -- Clock buffer output
I => ICAP_Clk -- Clock buffer input
);
ICAP_VIRTEX5_inst : ICAP_VIRTEX5
generic map (
ICAP_WIDTH => "X32") -- "X8", "X16" or "X32"
port map (
BUSY => open, -- Busy output
O => ICAP_Dout, -- 32-bit data output
CE => ICAP_CE, -- Clock enable input
CLK => ICAP_Clk1, -- Clock input
I => ICAP_Din, -- 32-bit data input
WRITE => ICAP_WR -- Write input
);
-- ICAP_Din(31 downto 8) <= x"000000"; -------------------------------End
U_ICAP_SM: block -------------------------------------
type State_Type is (State0, State00, State1, State2, State3, State4, State5, State6);
signal Pr_State, Nx_State : State_Type;
begin
Process(En,Clk)
begin
if (En = '0') then
Pr_State <= State0;
elsif (rising_edge(Clk)) then
Pr_State <= Nx_State;
end if;
end process;
process(Pr_State)
begin
case Pr_State is --*****
when State0 =>
Nx_State <= State00;
ROM_Address <= x"000";
ICAP_WR <= '1';
ROM_Clk <= '0';
ICAP_Clk <= '0';
ICAP_CE <= '1';
when State00 =>
Nx_State <= State1;
ICAP_WR <= '0';
when State1 =>
Nx_State <= State2;
ICAP_CE <= '0';
ROM_Clk <= '1';
when State2 =>
Nx_State <= State3;
ICAP_Din <= ROM_Data;
ROM_Clk <= '0';
when State3 =>
Nx_State <= State4;
ICAP_Clk <= '1';
when State4 =>
Nx_State <= State5;
ICAP_Clk <= '0';
when State5 =>
if (ROM_Address = conv_std_logic_vector(3134,12)) then
Nx_State <= State6;
ICAP_CE <= '1';
ROM_Address <= X"000";
else
Nx_State <= State1;
ROM_Address <= (ROM_Address + 1);
end if;
when State6 =>
ICAP_WR <= '1';
end case;
end process;
end Block U_ICAP_SM; -----------------------------------
end Behavioral;
I saved the bit stream (.coe file) of one of the counter (for example up-counter) in ROM. By default circuit is down counting, but when I exchange bit stream by icap (load .coe file of up-counter from ROM) nothing happens and circuit is counting down. (***** in the code)
how can I fix it?

Change VHDL testbench and 32bit-ALU with clock to one without

I wrote this VHDL-program vor an ALU and its testbench that is working:
ALU-code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity ALU_CLK is
port( Clk : in std_logic; --clock signal
InRegA,InRegB : in signed(31 downto 0); --input operands
InOp : in unsigned(2 downto 0); --Operation to be performed
OutReg : out signed(31 downto 0); --output of ALU
OutZero : out std_logic
);
end ALU_CLK;
architecture Behavioral of ALU_CLK is
signal Reg1,Reg2,Reg3 : signed(31 downto 0) := (others => '0');
begin
Reg1 <= INregA;
Reg2 <= InRegB;
OutReg <= Reg3;
process(Clk)
variable temp: signed(31 downto 0);
begin
if(rising_edge(Clk)) then
case InOp is
when "010" =>
temp := Reg1 + Reg2; --addition
when "000" =>
temp := Reg1 and Reg2; --AND gate
when "001" =>
temp := Reg1 or Reg2; --OR gate
when others =>
NULL;
end case;
if temp = (31 downto 0=>'0') then
OutZero <= '1';
else
OutZero <= '0';
end if;
Reg3 <= temp;
end if;
end process;
end Behavioral;
The testbench code:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
ENTITY tb IS
END tb;
ARCHITECTURE ALU_CLK OF tb IS
signal Clk : std_logic := '0';
signal A,B,R : signed(31 downto 0) := (others => '0');
signal Op : unsigned(2 downto 0) := (others => '0');
signal zero : std_logic :='0';
constant Clk_period : time := 10 ns;
BEGIN
uut: entity work.ALU_CLK PORT MAP (
Clk => Clk,
InRegA => A,
InRegB => B,
InOp => Op,
OutReg => R,
OutZero => zero
);
Clk_process :process
begin
Clk <= '0';
wait for Clk_period/2;
Clk <= '1';
wait for Clk_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
wait for Clk_period*1;
--test normal operations
A <= "00000000000000000000000000010011"; --19 in decimal
B <= "00000000000000000000000000001100"; --12 in decimal
Op <= "000"; wait for Clk_period; --Bitwise and A and B
Op <= "001"; wait for Clk_period; --Bitwise or B from A.
Op <= "010"; wait for Clk_period; --addition A nad B
wait;
end process;
END;
To shorten the code listings a bit I did not post all the operations the ALU does.
I can manage it to change the ALU to one without the clk but how can I test it with a testbench?
Even in a test bench for a module without a clock, it may be a good idea to have
a clock that can time the test events, and make it easier to see the test
progress in waveforms.
So after removal of the clock from the ALU, the test bench process can control
stimuli and do the checks like:
-- Combined stimuli and check process
process is
begin
...
-- === 2 + 2 test ===
-- Stimuli control
wait until rising_edge(clk);
InRegA <= to_signed(2, InRegA'length);
InRegB <= to_signed(2, InRegA'length);
InOp <= "010"; -- Add
-- Output check
wait until falling_edge(clk);
assert OutReg = InRegA + InRegB;
assert (OutZero = '1') = (OutReg = 0);
...
end process;
To simplify the check part, it can be moved to a separate process and the check
can be made depending on the operation like:
-- Check process
process (clk) is
begin
if falling_edge(clk) then
if check then
-- OutReg check
case InOp is
when "010" => assert OutReg = InRegA + InRegB; -- Add
when "000" => assert OutReg = (InRegA and InRegB); -- And
when "001" => assert OutReg = (InRegA or InRegB); -- Or
when others => report "Unsupported operation" severity ERROR;
end case;
-- OutZero check
assert (OutZero = '1') = (OutReg = 0);
end if;
end if;
end process;
The check signal is controlled by the stimuli process, to guard when the
check is to be made, in order to avoid false errors in startup or for other
special conditions.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity alu32bit is
port(en:in STD_LOGIC;
opc:in STD_LOGIC_VECTOR(3 downto 0);
a_in,b_in:in STD_LOGIC_VECTOR(31 downto 0);
y_op:out STD_LOGIC_VECTOR(31 downto 0));
end alu32 bit;
architecture Behavioral of alu32 bit is
begin
Process(en,a_in,b_in,opc)
begin
if(en='1')then
when "0001"=>y_op<=a_in+b_in;
when "0010"=>y_op<=a_in-b_in;
when "0011"=>y_op<=not a_in;
when "0100"=>y_op<=a_in and b_in;
when "0101"=>y_op<=a_in or b_in;
when "0110"=>y_op<=a_in nand b_in;
when "0111"=>y_op<=a_in xor b_in;
when others=>null;
end case;
else
y_op<="ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ";
end if;
end process;
end Behavioral;
In the end I got this:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity ALU_32 is
port(
InRegA,InRegB : in signed(31 downto 0); --input operands
InOp : in unsigned(2 downto 0); --Operation to be performed
OutReg : out signed(31 downto 0); --output of ALU
OutZero : out std_logic
);
end ALU_32;
architecture Behavioral of ALU_32 is
--temporary signal declaration.
signal Reg1,Reg2,Reg3 : signed(31 downto 0) := (others => '0');
begin
Reg1 <= InRegA;
Reg2 <= InRegB;
OutReg <= Reg3;
process(InOp, InRegA, inRegB)
variable temp: signed(31 downto 0);
begin
case InOp is
when "010" =>
temp := Reg1 + Reg2; --addition
when "110" =>
temp := Reg1 - Reg2; --subtraction
when "000" =>
temp := Reg1 and Reg2; --AND gate
when "001" =>
temp := Reg1 or Reg2; --OR gate
when "100" =>
temp := Reg1 nor Reg2; --NOR gate
when "011" =>
temp := Reg1 xor Reg2; --XOR gate
when "101" =>
temp := not Reg1; --NOT gate
when "111" =>
if Reg1 < Reg2 then --SLT (set on less than) gate
temp := (others => '1');
else
temp := (others => '0');
end if;
when others =>
NULL;
end case;
if temp = (31 downto 0=>'0') then
OutZero <= '1';
else
OutZero <= '0';
end if;
Reg3 <= temp;
end process;
end Behavioral;
And the working testbench is:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
ENTITY tb2 IS
END tb2;
ARCHITECTURE ALU_32 OF tb2 IS
COMPONENT ALU_32
PORT(
InRegA : IN signed(31 downto 0);
InRegB : IN signed(31 downto 0);
InOp : IN unsigned(2 downto 0);
OutReg : OUT signed(31 downto 0);
OutZero : OUT std_logic
);
END COMPONENT;
--Inputs
signal InRegA : signed(31 downto 0) := (others => '0');
signal InRegB : signed(31 downto 0) := (others => '0');
signal InOp : unsigned(2 downto 0) := (others => '0');
--Outputs
signal OutReg : signed(31 downto 0);
signal OutZero : std_logic;
-- No clocks detected in port list. Replace <clock> below with
-- appropriate port name
--constant <InOp>_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: ALU_32 PORT MAP (
InRegA => InRegA,
InRegB => InRegB,
InOp => InOp,
OutReg => OutReg,
OutZero => OutZero
);
-- Stimulus process
stim_proc: process
begin
-- hold reset state for 100 ns.
wait for 100 ns;
-- insert stimulus here
--test normal operations
InRegA <= "00000000000000000000000000010011"; --19 in decimal
InRegB <= "00000000000000000000000000001100"; --12 in decimal
InOp <= "000"; wait for 100 ns; --Bitwise and A and B
InOp <= "001"; wait for 100 ns; --Bitwise or B from A.
InOp <= "010"; wait for 100 ns; --addition A nad B
InOp <= "100"; wait for 100 ns; --Bitwise NOR of A and B
InOp <= "011"; wait for 100 ns; --Bitwise XOR of A and B
InOp <= "110"; wait for 100 ns; --substract A and B
InOp <= "101"; wait for 100 ns; --Bitwise NOT of A
InOp <= "111"; wait for 100 ns; --Bitwise SLT of A and B
-- test SLT the other way around
InRegB <= "00000000000000000000000000010011"; --19 in decimal
InRegA <= "00000000000000000000000000001100"; --12 in decimal
InOp <= "111"; wait for 100 ns; --Bitwise SLT of A and B
-- test Branch equal that substraction is 0 and zero is 1
InRegA <= "00000000000000000000000000001011"; --11 in decimal
InRegB <= "00000000000000000000000000001011"; --11 in decimal
InOp <= "110"; wait for 100 ns; --substract A and B
wait;
end process;
END;
Here is the result of the simulation:

How to add std_logic to an integer value

I am trying to run two 7 segments here, I have searched everywhere but could not find a satisfactory reply, how can I add 1 to a std_logic ? I tried the logic_arith library as well but nothing works. I read somewhere that i gotta use a (0 to 0) vector but umm i didn't really get that part. Here is my code
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use ieee.std_logic_arith.all;
entity blah is
Port ( clk : in STD_LOGIC;
anode: out STD_LOGIC_VECTOR (3 downto 0);
segment: out STD_LOGIC_VECTOR (6 downto 0));
end blah;
architecture Behavioral of blah is
signal sel: STD_LOGIC;
signal r_anode: STD_LOGIC_VECTOR (3 downto 0);
begin
anode <= r_anode;
process (clk) begin
if (clk'event and clk = '1') then
sel <= sel+1;
end if;
end process;
process (sel) begin
case sel is
when '0' => r_anode <= "1110";
when '1' => r_anode <= "1101";
when others => r_anode <= "1111";
end case;
case r_anode is
when "1110" => segment <= "0100100";
when "1101" => segment <= "0010010";
when others => segment <= "1111111";
end case;
end process;
end;
And the error
ERROR:HDLParsers:808 - "E:/Xilinx Projects/blah/blah.vhd" Line 19. + can not have such operands in this context.
The sel is only a single bit, so adding 1 is like a not sel.
However, if sel is more bits in a std_logic_vector, you can add a
natural to std_logic_vector as unsigned with:
sel <= std_logic_vector(unsigned(sel) + 1);
Use only ieee.numeric_std, thus remove the ieee.std_logic_arith, since
std_logic_arith is not a standard library (Synopsys proprietary).

Resources