I try to implement a divisor for std_logic_vector with the language VHDL.
After I have implemented it, I have to use GHDL but encountered this error :
vhdl:error: bound check failure at divisor.vhdl
It's correspond to this :
else ....
nb_reg <= (2*nb);
My code is :
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity div is
generic
(
DATA_WIDTH : natural := 8;
ADDR_WIDTH : natural := 3
);
port (
clk : in std_logic;
reset : in std_logic;
raddr : in natural range 0 to 2**ADDR_WIDTH - 1;
waddr : in natural range 0 to 2**ADDR_WIDTH - 1;
max : in std_logic_vector((DATA_WIDTH -1) downto 0);
data : in std_logic_vector((DATA_WIDTH -1) downto 0);
q : out std_logic_vector((DATA_WIDTH -1) downto 0)
);
end div;
architecture rtl of div is
-- Build a 2-D array type for the RAM
subtype word_t is unsigned((DATA_WIDTH-1) downto 0);
type memory_t is array(natural range <>) of word_t;
-- Declare the RAM signal.
signal ram, div : memory_t((2**ADDR_WIDTH)-1 downto 0);
-- Declare the n and max_reg signal.
signal n,m : unsigned(((2*DATA_WIDTH)-1) downto 0);
signal max_reg : unsigned(((2*DATA_WIDTH)-1) downto 0);
signal nb : unsigned(((2*DATA_WIDTH)-1) downto 0);
signal nb_reg : unsigned(((4*DATA_WIDTH)-3) downto 0);
-- Build div_reg, ram_reg
type memory_reg is array(natural range <>) of unsigned(((2*DATA_WIDTH)-1) downto 0);
signal ram_reg: memory_reg((2**ADDR_WIDTH)-1 downto 0);
begin
process(clk,reset)
begin
if (reset = '1') then
ram(waddr) <= X"00";
div(waddr) <= X"00";
max_reg <= X"0000";
ram_reg(waddr) <= X"0000";
n <= X"0000";
nb <= X"0000";
--nb_reg(((4*DATA_WIDTH)-3) downto 0) <= "0";
m <= X"0000";
elsif(rising_edge(clk)) then
ram(waddr) <= unsigned(data);
max_reg((DATA_WIDTH -1) downto 0) <= unsigned(max);
ram_reg(waddr)((DATA_WIDTH-1) downto 0) <= ram(waddr)((DATA_WIDTH-1) downto 0);
nb <= (nb+1);
if (ram(waddr) = max_reg)then
div(waddr) <= div(waddr)+1;
elsif (ram(waddr) > max_reg)then
while ((div(waddr)*(ram(waddr)) > max_reg) or (m <(DATA_WIDTH -1))) loop
div(waddr) <= (div(waddr))+1;
max_reg <= (max_reg) - (ram_reg(waddr));
m <= m+1;
end loop;
m <= (m-1);
while (((div(waddr)*ram_reg(waddr)) < max_reg-1) or (n <(DATA_WIDTH)-(m))) loop
ram_reg(waddr)(((2*DATA_WIDTH)-1) downto 1) <= ram_reg(waddr)(((2*DATA_WIDTH)-2) downto 0);
ram_reg(waddr)(0) <= '0';
n <= n+1;
nb_reg <= (nb*2);
nb(((2*DATA_WIDTH)-1) downto 0) <= nb_reg(((2*DATA_WIDTH)-1) downto 0);
end loop;
ram_reg(waddr) <= ram_reg(waddr) - (max_reg);
div(waddr) <= (div(waddr))+(1/(nb));
else
while (((div(waddr)*ram_reg(waddr)) < max_reg-1) or (n <(DATA_WIDTH)-(m))) loop
ram_reg(waddr)(((2*DATA_WIDTH)-1) downto 1) <= ram_reg(waddr)(((2*DATA_WIDTH)-2) downto 0);
ram_reg(waddr)(0) <= '0';
n <= n+1;
nb_reg <= (2*nb);
nb(((2*DATA_WIDTH)-1) downto 0) <= nb_reg(((2*DATA_WIDTH)-1) downto 0);
end loop;
ram_reg(waddr) <= ram_reg(waddr) - (max_reg);
div(waddr) <= (div(waddr))+(1/(nb));
end if;
else null;
end if;
end process;
q <= std_logic_vector(div(waddr));
end rtl;
The test bench :
-- descrizione del Test_bench
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity div_tb is
end div_tb;
architecture behaviour of div_tb is
--dichiarazione dei COMPONENT ovvero la Unit Under Test
component div is
generic
(
DATA_WIDTH : natural := 8;
ADDR_WIDTH : natural := 3
);
port
(
clk : in std_logic;
reset : in std_logic;
raddr : in natural range 0 to 2**ADDR_WIDTH - 1;
waddr : in natural range 0 to 2**ADDR_WIDTH - 1;
max : in std_logic_vector((DATA_WIDTH -1) downto 0);
data : in std_logic_vector((DATA_WIDTH -1) downto 0);
q : out std_logic_vector((DATA_WIDTH -1) downto 0)
);
end component;
-- Clock period definitions
constant clk_period : time := 1 us;
constant DATA_WIDTH : natural := 8;
constant ADDR_WIDTH : natural := 3;
signal CLK_tb: std_logic := '0';
signal RESET_tb: std_logic := '1';
signal raddr_tb, waddr_tb : natural range 0 to 2**ADDR_WIDTH - 1;
signal data_tb, q_tb, max_tb : std_logic_vector((DATA_WIDTH -1) downto 0);
signal I : integer := 0; -- variabile per il conteggio dei clock
begin
clk_process: process --processo di generazione del CLK
begin
CLK_tb <= '0';
wait for clk_period/2;
CLK_tb <= '1';
wait for clk_period/2;
I<=I+1;
if I=200 then wait; -- durata della simulazione: 30 colpi di CLK
else null;
end if;
end process;
-- istanziazione della Unit Under Test
UUT: div generic map (ADDR_WIDTH => 3, DATA_WIDTH => 8)
port map (clk=>clk_tb, reset=>RESET_tb, raddr => raddr_tb, waddr => waddr_tb , data => data_tb, q => q_tb, max => max_tb);
stimoli: process
begin
RESET_tb <= '1';
wait for clk_period*3;
RESET_tb <= '0';
wait;
end process;
we: process
begin
max_tb <= "11100110";
wait;
end process;
Data : process
begin
data_tb <= "00000000"; raddr_tb <= 0; waddr_tb <= 0; wait for clk_period*3;
data_tb <= "01010110"; raddr_tb <= 1; waddr_tb <= 1; wait for clk_period*8;
data_tb <= "01000110"; raddr_tb <= 2; waddr_tb <= 2; wait for clk_period*8;
data_tb <= "11001110"; raddr_tb <= 3; waddr_tb <= 3; wait for clk_period*8;
data_tb <= "01000111"; raddr_tb <= 4; waddr_tb <= 4; wait for clk_period*8;
data_tb <= "11100110"; raddr_tb <= 5; waddr_tb <= 5; wait for clk_period*8;
data_tb <= "01000110"; raddr_tb <= 6; waddr_tb <= 6; wait for clk_period*8;
data_tb <= "01010110"; raddr_tb <= 7; waddr_tb <= 7; wait for clk_period*8;
wait;
end process;
end behaviour;
I use the 2007 version of GHDL and it is not possible for me to update, my teacher wants me to use this one.
Could somebody help me with this code?
The multiplication operator in the numeric_std package is defined thus for multiplying a natural by an unsigned:
-- Id: A.18
function "*" (L: NATURAL; R: UNSIGNED) return UNSIGNED;
-- Result subtype: UNSIGNED((R'LENGTH+R'LENGTH-1) downto 0)
-- Result: Multiplies an UNSIGNED vector, R, with a nonnegative
-- INTEGER, L. L is converted to an UNSIGNED vector of
-- SIZE R'LENGTH before multiplication.
As you can see, the output is twice the width of the unsigned argument minus 1. In this line
nb <= std_logic_vector(2*unsigned(nb));
you are assigning the result back to the unsigned operand, which obviously is not a different width to itself.
So, you either need an intermediate variable of the right width or perhaps a shift left?
Related
I've been learning VHDL for a while and I'm making a project right now. I made a NCO (Numerically controlled Oscillator) and a cordic algorithm to produce sine and cosine with a certain frequency.
I don't know why I get spikes on my waves in Modelsim. I guess they are caused by the case statement when it changes the quadrant for the cordic algorithm to work with angles between -180 and +180.
I've read that it could be a "normal" behavior of Modelsim because of the iterations of the simulator (VHDL delta cycles). But I don't know how and if I should fix them.
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
ENTITY phase_accumulator_module IS
GENERIC (
LGTBL: INTEGER := 16; --lunghezza table log base 2
W: INTEGER := 32;
OW: INTEGER := 16
);
PORT (
clk: IN STD_LOGIC;
reset: IN STD_LOGIC;
i_dphase: IN STD_LOGIC_VECTOR(W-1 DOWNTO 0);
o_val: BUFFER STD_LOGIC_VECTOR(W-1 DOWNTO 0);
o_val_test:BUFFER STD_LOGIC_VECTOR(OW-1 DOWNTO 0);
o_val_laser: BUFFER STD_LOGIC_VECTOR(W-1 DOWNTO 0);
quadrant: BUFFER STD_LOGIC_VECTOR(1 DOWNTO 0)
);
END phase_accumulator_module;
ARCHITECTURE behave OF phase_accumulator_module IS
SIGNAL r_step,r_step_laser,r_step_test: STD_LOGIC_VECTOR(W-1 DOWNTO 0) := (OTHERS => '0');
SIGNAL r_phase,r_phase_laser,r_phase_test: STD_LOGIC_VECTOR(W-1 DOWNTO 0) := (OTHERS => '0');
SIGNAL r_phase_pipe,r_phase_laser_pipe: STD_LOGIC_VECTOR(W-1 DOWNTO 0) := (OTHERS => '0');
CONSTANT P: INTEGER := LGTBL;
BEGIN
R_Step_pro: PROCESS(clk,reset)
BEGIN
IF(reset='1') THEN
r_step <= (OTHERS=>'0');
r_step_test <= (OTHERS=>'0');
r_step_laser <= (OTHERS=>'0');
ELSE IF(rising_edge(clk)) THEN
r_step <= i_dphase; -- 2^W*f/fs
r_step_test <= i_dphase; --test signal
r_step_laser <= STD_LOGIC_VECTOR(SHIFT_RIGHT(UNSIGNED(i_dphase),1));
END IF;
END IF;
END PROCESS R_Step_pro;
R_phase_pro: PROCESS(clk,reset)
BEGIN
IF(reset='1') THEN
r_phase <= (OTHERS=>'0');
r_phase_test <= (OTHERS=>'0');
r_phase_laser <= (OTHERS=>'0');
o_val <= (OTHERS=>'0');
o_val_test <= (OTHERS=>'0');
o_val_laser <= (OTHERS=>'0');
ELSE IF(rising_edge(clk)) THEN
r_phase <= STD_LOGIC_VECTOR(UNSIGNED(r_phase) + UNSIGNED(r_step));
r_phase_test <= STD_LOGIC_VECTOR(UNSIGNED(r_phase_test) + UNSIGNED(r_step_test)); --test signal
r_phase_laser <= STD_LOGIC_VECTOR(UNSIGNED(r_phase_laser) + UNSIGNED(r_step_laser));
quadrant <= r_phase(W-1 DOWNTO w-2);
CASE quadrant IS
WHEN "00" | "11" =>
r_phase_pipe <= r_phase;
r_phase_laser_pipe <= r_phase_laser;
WHEN "01" =>
r_phase_pipe <= "00" & r_phase(W-3 DOWNTO 0);
r_phase_laser_pipe <= "00" & r_phase_laser(W-3 DOWNTO 0);
WHEN "10" =>
r_phase_pipe <= "11" & r_phase(W-3 DOWNTO 0);
r_phase_laser_pipe <= "11" & r_phase_laser(W-3 DOWNTO 0);
WHEN OTHERS =>
null;
END CASE;
o_val_test <= r_phase_test(W-1 DOWNTO W-P);
o_val <= r_phase_pipe;
o_val_laser <= r_phase_laser_pipe;
END IF;
END IF;
END PROCESS R_phase_pro;
END behave;
This is the cordic algotithm vhdl file:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
ENTITY signal_gen_cordic_module IS
GENERIC (
bits: INTEGER := 16;
bits_out_c: INTEGER := 32;
iter : INTEGER := 32
);
PORT (
clk: IN STD_LOGIC;
reset: IN STD_LOGIC;
locked: IN STD_LOGIC;
z0: IN STD_LOGIC_VECTOR (bits_out_c-1 DOWNTO 0);
quadrant: IN STD_LOGIC_VECTOR(1 DOWNTO 0);
sine,cosine: BUFFER STD_LOGIC_VECTOR(bits-1 DOWNTO 0)
);
END signal_gen_cordic_module;
ARCHITECTURE behave OF signal_gen_cordic_module IS
TYPE temp IS ARRAY (0 TO iter-1) OF STD_LOGIC_VECTOR(bits_out_c-1 DOWNTO 0);
SIGNAL x_temp,y_temp,z_temp: temp;
CONSTANT x0: SIGNED(bits_out_c-1 DOWNTO 0) := "00000000000000000010111100011010"; --0.6072*2^16
CONSTANT y0: SIGNED(bits_out_c-1 DOWNTO 0) := "00000000000000000000000000000000";
SIGNAL x00,y00: SIGNED(bits_out_c-1 DOWNTO 0);
TYPE atand IS ARRAY (0 TO iter-1) OF STD_LOGIC_VECTOR(bits_out_c-1 DOWNTO 0);
CONSTANT arctan: atand :=
(
x"20000000",
x"12E4051E",
x"09FB385B",
x"051111D4",
x"028B0D43",
x"0145D7E1",
x"00A2F61E",
x"00517C55",
x"0028BE53",
x"00145F2F",
x"000A2F98",
x"000517CC",
x"00028BE6",
x"000145F3",
x"0000A2FA",
x"0000517D",
x"000028BE",
x"0000145F",
x"00000A30",
x"00000518",
x"0000028C",
x"00000146",
x"000000A3",
x"00000051",
x"00000029",
x"00000014",
x"0000000A",
x"00000005",
x"00000003",
x"00000001",
x"00000001",
x"00000000"
);
BEGIN
PROCESS(clk,reset)
BEGIN
IF(reset='1') THEN
cosine <= (OTHERS=>'0');
sine <= (OTHERS=>'0');
FOR i IN iter-1 DOWNTO 0 LOOP
x_temp(i) <= (OTHERS=>'0');
y_temp(i) <= (OTHERS=>'0');
z_temp(i) <= (OTHERS=>'0');
END LOOP;
ELSE IF(rising_edge(clk)) THEN
IF(locked='1') THEN
IF(quadrant="00" OR quadrant="11") THEN
x00 <= x0;
y00 <= y0;
ELSE IF(quadrant="01") THEN
x00 <= -y0;
y00 <= x0;
ELSE
x00 <= y0;
y00 <= -x0;
END IF;
END IF;
x_temp(0) <= STD_LOGIC_VECTOR(x00);
y_temp(0) <= STD_LOGIC_VECTOR(y00);
z_temp(0) <= z0;
FOR i IN 0 TO iter-2 LOOP
IF(z_temp(i)(z0'HIGH)='1') THEN
x_temp(i+1) <= STD_LOGIC_VECTOR(SIGNED(x_temp(i)) + SHIFT_RIGHT(SIGNED(y_temp(i)),i));
y_temp(i+1) <= STD_LOGIC_VECTOR(SIGNED(y_temp(i)) - SHIFT_RIGHT(SIGNED(x_temp(i)),i));
z_temp(i+1) <= STD_LOGIC_VECTOR(SIGNED(z_temp(i)) + SIGNED(arctan(i)));
ELSE
x_temp(i+1) <= STD_LOGIC_VECTOR(SIGNED(x_temp(i)) - SHIFT_RIGHT(SIGNED(y_temp(i)),i));
y_temp(i+1) <= STD_LOGIC_VECTOR(SIGNED(y_temp(i)) + SHIFT_RIGHT(SIGNED(x_temp(i)),i));
z_temp(i+1) <= STD_LOGIC_VECTOR(SIGNED(z_temp(i)) - SIGNED(arctan(i)));
END IF;
END LOOP;
cosine <= STD_LOGIC_VECTOR(RESIZE(SIGNED(x_temp(iter-1)),bits));
sine <= STD_LOGIC_VECTOR(RESIZE(SIGNED(y_temp(iter-1)),bits));
END IF;
END IF;
END IF;
END PROCESS;
END behave;
My modelsim version is 10.5b. Thank you for any help! :)
I have to develop a SDRAM controller for a class project in VHDL. But this is my first time working with VHDL, that has a very important learning curve.
I have downloaded a SDRAM controller from github (https://github.com/christianmiyoshi/SDRAM_Controller_VHDL/blob/master/sdram_controller.vhd) and I am trying to complete it.
I am trying to write a data in an address and later read it, but I cant read a single data. I dont know if my problem is in the writing or in the reading process.
Can anybody help me, please?
Thank you all!
library ieee;
use ieee.numeric_std.all;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity ram_controller is
port(
clk : in std_logic;
reset: in std_logic;
refresh: in std_logic;
read_write_enable: in std_logic;
write_n: in std_logic;
address: in std_logic_vector(21 downto 0);
data_in: in std_logic_vector(15 downto 0);
dqmu: in std_logic;
dqml: in std_logic;
ready: out std_logic;
done: out std_logic;
data_out: out std_logic_vector(15 downto 0);
single_burst: in std_logic; --0 single y 1 burst
SDRAM_CKE: out std_logic;
SDRAM_CS_N: out std_logic;
SDRAM_RAS_N: out std_logic;
SDRAM_CAS_N: out std_logic;
SDRAM_WE_N: out std_logic;
SDRAM_BA: out std_logic_vector(1 downto 0);
SDRAM_SA: out std_logic_vector(11 downto 0);
SDRAM_DQ: inout std_logic_vector(15 downto 0);
SDRAM_DQM: out std_logic_vector(1 downto 0)
);
end entity;
architecture behavior of ram_controller is
type state_type is (init_ckeLow, init_stableClock, init_wait, init_nopCommand, init_prechargeAll, init_refresh_1, init_mode, init_refresh_2, idle, refresh_state, activate_row, activate_rcd, read_write, ras1, ras2, precharge);
signal state: state_type := init_ckeLow;
signal ticks: std_logic_vector(7 downto 0) := (others => '0');
signal ticks_ref: integer := 0;
signal ticks_ref_refresh: integer := 0;
constant burstMode: std_logic := '0';
constant casLatency: std_logic_vector(2 downto 0) := "010";
constant burstType: std_logic := '0';
constant burstLength: std_logic_vector(2 downto 0) := "000";
--signal highz_output: std_logic:= '0';
constant MODE_REG: std_logic_vector(11 downto 0) := "00" & burstMode & "00" & casLatency & burstType & burstLength;
constant MODE_REG_BURST: std_logic_vector(11 downto 0) := "000000100111";
signal command: std_logic_vector(3 downto 0);
signal row: std_logic_vector(11 downto 0);
signal column: std_logic_vector(7 downto 0);
signal bank: std_logic_vector(1 downto 0);
signal sd_busdir_x: std_logic:='0';
-- Command truth table
-- CS_N, RAS_N, CAS_N, WE_N
constant CMD_ACTIVATE: std_logic_vector(3 downto 0) := "0011";
constant CMD_PRECHARGE: std_logic_vector(3 downto 0) := "0010";
constant CMD_WRITE: std_logic_vector(3 downto 0) := "0100";
constant CMD_READ: std_logic_vector(3 downto 0) := "0101";
constant CMD_MODE: std_logic_vector(3 downto 0) := "0000";
constant CMD_NOP: std_logic_vector(3 downto 0) := "0111";
constant CMD_REFRESH: std_logic_vector(3 downto 0) := "0001";
signal address_buffer: std_logic_vector(21 downto 0) := (others => '0');
signal data_in_buffer: std_logic_vector(15 downto 0) := (others => '0');
signal dqu_buffer: std_logic := '0';
signal dql_buffer: std_logic := '0';
signal ready_buffer: std_logic := '0';
signal done_buffer: std_logic := '0';
signal data_out_buffer: std_logic_vector(15 downto 0) := (others => '0');
signal CKE: std_logic;
signal CS_N: std_logic;
signal RAS_N: std_logic;
signal CAS_N: std_logic;
signal WE_N: std_logic;
signal BA: std_logic_vector(1 downto 0);
signal SA: std_logic_vector(11 downto 0);
signal DQ: std_logic_vector(15 downto 0);
signal DQM: std_logic_vector(1 downto 0);
signal contador : std_logic_vector(15 downto 0) := x"0000";
signal modo: std_logic := '0';
begin
(CS_N, RAS_N, CAS_N, WE_N) <= command;
SDRAM_CKE <= CKE;
SDRAM_CS_N <= CS_N;
SDRAM_RAS_N <= RAS_N;
SDRAM_CAS_N <= CAS_N;
SDRAM_WE_N <= WE_N;
SDRAM_BA <= BA;
SDRAM_SA <= SA;
--SDRAM_DQ <= DQ;
SDRAM_DQM <= DQM;
--SA <= address_buffer;
SDRAM_DQ <= data_in_buffer when sd_busdir_x = '1' else (others => 'Z');
DQM <= dqu_buffer & dql_buffer;
ready <= ready_buffer;
done <= done_buffer;
data_out <= data_out_buffer;
bank <= address(21 downto 20);
row <= address(19 downto 8);
column <= address(7 downto 0);
process(clk, reset)
begin
if reset = '0' then
state <= init_ckeLow;
ticks_ref <= 0;
elsif rising_edge(clk) then
if ticks_ref /= 0 then
ticks_ref <= ticks_ref - 1;
else
-- Micron datasheet instructions
-- Frequency = 100 Mhz => period of 10ns
-- 1: Apply Vdd and Vddq simultaneously
case state is
when init_ckeLow =>
-- 2: Assert and hold CKE ant LVTTL logic low
ticks_ref <= 10;
CKE <= '0';
state <= init_stableClock;
when init_stableClock =>
-- 3: Provide stable clock
ticks_ref <= 10;
state <= init_wait;
when init_wait=>
-- 4: Wait at least 100us
-- 5: bring cke high at some point of the period
-- with command inhibit or nop
--ticks_ref <= 10000;
ticks_ref <= 2; -- debugadd
state <= init_nopCommand;
when init_nopCommand =>
--ticks_ref <= 10000;
ticks_ref <= 2; -- debug
CKE <= '1';
command <= CMD_NOP;
state <= init_prechargeAll;
when init_prechargeAll =>
-- 6: perform precharge all
-- 7: wait at leas t_RP
command <= CMD_PRECHARGE;
BA <= "00";
SA(10) <= '1'; -- all banks
ticks_ref <= 2;
ticks_ref_refresh <= 8;
state <= init_refresh_1;
when init_refresh_1 =>
-- auto refresj period: < 64 ns
if ticks_ref_refresh = 0 then
state <= init_mode;
else
ticks_ref_refresh <= ticks_ref_refresh - 1;
command <= CMD_REFRESH;
ticks_ref <= 7;
end if;
when init_mode =>
command <= CMD_MODE;
if single_burst = '0' then
SA <= MODE_REG;
modo <= '0';
else
SA <= MODE_REG_BURST;
modo <= '1';
end if;
BA <= "00";
ticks_ref <= 2;
ticks_ref_refresh <= 8;
state <= init_refresh_2;
when init_refresh_2 =>
if ticks_ref_refresh = 0 then
state <= idle;
--done_buffer <= '1';
else
ticks_ref_refresh <= ticks_ref_refresh - 1;
command <= CMD_REFRESH;
ticks_ref <= 7;
end if;
when idle =>
done_buffer <= '0';
contador <= (others => '0');
if read_write_enable = '1' then
-- tras: active to precharge: 45 ns min, 120000ns max
state <= activate_row;
command <= CMD_ACTIVATE;
SA <= row;
BA <= bank;
--done_buffer <= '0';
elsif refresh = '1' then
state <= refresh_state;
command <= CMD_REFRESH;
ticks_ref <= 7;
--done_buffer <= '0';
end if;
when refresh_state =>
state <= idle;
--done_buffer <= '1';
when activate_row =>
--trcd 20 ns
command <= CMD_NOP;
state <= activate_rcd;
data_in_buffer <= data_in;
ticks_ref <= 1;
when activate_rcd =>
-- trcs = 20ns min
state <=read_write;
SA <= "0000" & column;
if write_n = '0' then
command <= CMD_WRITE;
dqu_buffer <= dqmu;
dql_buffer <= dqml;
sd_busdir_x <= '1';
else
command <= CMD_READ;
end if;
when read_write =>
--command <= CMD_NOP;
state <= ras1;
--if modo='0' then
--sd_busdir_x <= '0';
--end if;
when ras1 =>
state <= ras2;
command <= CMD_NOP;
when ras2 =>
-- trp = 20ns min
if modo='1' and contador <= x"00FF" then
data_in_buffer <= data_in;
state <= ras2;
contador <= contador +1;
else
contador <= (others => '0');
state <= precharge;
sd_busdir_x <= '0';
command <= CMD_PRECHARGE;
SA(10) <= '1';
data_out_buffer <= SDRAM_DQ;
ticks_ref <= 2;
end if;
when precharge =>
state <= idle;
done_buffer <= '1';
ticks_ref <= 1;
end case;
end if;
end if;
end process;
end architecture;
[enter image description here][1]
[1]: https://i.stack.imgur.com/CaqqL.png
I have a problem with code snippet from http://langster1980.blogspot.com/2015/09/more-on-seven-segment-displays-and.html
My code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
entity main is
port (
clock_in : in std_logic;
Seven_Segment_Enable : out std_logic_vector(2 downto 0);
Seven_Segment_Display : out std_logic_vector(7 downto 0)
);
end main;
architecture Behavioral of main is
signal refresh_count : integer := 0;
signal refresh_clk : std_logic := '1';
signal second_count : integer := 0;
signal second_clk : std_logic := '1';
signal digit_sel : unsigned(1 downto 0);
signal bcd : integer := 0;
signal Seven_Segment_Display_output : std_logic_vector (7 downto 0) := (others => '0');
signal bcd0, bcd1, bcd2 : integer := 0;
signal unit_count : integer := 0;
signal ten_count : integer := 0;
signal hundred_count : integer := 0;
begin
process(Clock_in)
begin
if(clock_in'event and clock_in='1') then
refresh_count <= refresh_count+1;
second_count <= second_count+1;
if(second_count = 750000) then
second_clk <= not second_clk;
second_count <= 1;
end if;
if(refresh_count = 1200) then
refresh_clk <= not refresh_clk;
refresh_count <= 1;
end if;
end if;
end process;
process(second_clk)
begin
if(second_clk'event and second_clk='1') then
bcd0 <= 0;
bcd1 <= 1;
bcd2 <= 2;
end if;
end process;
process(refresh_clk)
begin
if(refresh_clk' event and refresh_clk='1') then
digit_sel <= digit_sel + 1;
end if;
end process;
with digit_sel select
bcd <= bcd0 when "00",
bcd1 when "01",
bcd2 when others;
with digit_sel select
Seven_Segment_Enable <= "110" when "00",
"101" when "01",
"011" when others;
with bcd select
Seven_Segment_Display_output(7 downto 0) <= B"00000011" when 0,
B"11110011" when 1,
B"00100101" when 2,
B"01100001" when 3,
B"11010001" when 4,
B"01001001" when 5,
B"00001001" when 6,
B"11100011" when 7,
B"00000001" when 8,
B"01000001" when 9,
B"11111111" when others;
Seven_Segment_Display(7 downto 0) <= Seven_Segment_Display_output(7 downto 0);
end Behavioral;
My problem is with draw on display.
According to code should be draw number 012, but me result is
(Click to enlarge)
and I don't know how to fix it.
Don't you know what to do?
Sorry for my bad English.
I have a problem with VHDL ALU code. I have to make simple ALU with 4 operations with 4-bit operands. I implemented these operations correctly and they work well. For executing I use E2LP board. For choosing the operation I selected 4 JOY buttons,one for each operation. Problem is that when I press button to execute operation and depress it I want result to stay on LEDs while I don't select any other operation, but that's not happening. For first 5 LEDs this works fine, but upper 3 not.This only works for one operation. My simulation results are correct. Here is code an schema of project.Thank you in advance.
---------------------------------------------------------------------------------- Control logic
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
Port ( --clk : in STD_LOGIC;
in_saberi : in STD_LOGIC;
in_mnozi : in STD_LOGIC;
in_ili : in STD_LOGIC;
in_rotiraj : in STD_LOGIC;
out_saberi : out STD_LOGIC;
out_mnozi : out STD_LOGIC;
out_ili : out STD_LOGIC;
out_rotiraj : out STD_LOGIC);
end upravljanje;
architecture Behavioral of upravljanje is
signal tmps : std_logic := '1';
signal tmpm : std_logic := '1';
signal tmpi : std_logic := '1';
signal tmpr : std_logic := '1';
begin
logika : process(in_saberi,in_mnozi,in_ili,in_rotiraj)
begin
if (in_saberi='0' and in_mnozi='1' and in_ili='1' and in_rotiraj='1') then
tmps <= in_saberi;
tmpm <= in_mnozi;
tmpi <= in_ili;
tmpr <= in_rotiraj;
elsif (in_mnozi='0' and in_saberi='1' and in_ili='1' and in_rotiraj='1') then
tmps <= in_saberi;
tmpm <= in_mnozi;
tmpi <= in_ili;
tmpr <= in_rotiraj;
elsif (in_saberi='1' and in_mnozi='1' and in_ili='0' and in_rotiraj='1') then
tmps <= in_saberi;
tmpm <= in_mnozi;
tmpi <= in_ili;
tmpr <= in_rotiraj;
elsif (in_saberi='1' and in_mnozi='1' and in_ili='1' and in_rotiraj='0') then
tmps <= in_saberi;
tmpm <= in_mnozi;
tmpi <= in_ili;
tmpr <= in_rotiraj;
elsif (in_saberi='1' and in_mnozi='1' and in_ili='1' and in_rotiraj='1') then
tmps <= tmps;
tmpm <= tmpm;
tmpi <= tmpi;
tmpr <= tmpr;
else
tmps <= '1';
tmpm <= '1';
tmpi <= '1';
tmpr <= '1';
end if;
end process logika;
out_saberi <= tmps;
out_mnozi <= tmpm;
out_ili <= tmpi;
out_rotiraj <= tmpr;
end Behavioral;
--------------------------------------------------------------------------
-- this is for operation add
entity sabirac is
Port ( clk : in STD_LOGIC;
data1 : in STD_LOGIC_VECTOR (3 downto 0);
data2 : in STD_LOGIC_VECTOR (3 downto 0);
saberi : in STD_LOGIC;
result : out STD_LOGIC_VECTOR (7 downto 0));
end sabirac;
architecture Behavioral of sabirac is
signal c : std_logic_vector (5 downto 0) := "000000";
signal tmp : std_logic_vector (7 downto 0) := "00000000";
begin
sabiranje : process(clk,saberi)
begin
if (saberi='0') then
tmp(0) <= data1(0) xor data2(0);
c(0) <= data1(0) and data2(0);
tmp(1) <= data1(1) xor data2(1) xor c(0);
c(1) <= (data1(1) and data2(1)) or (data1(1) and c(0)) or (data2(1) and c(0));
tmp(2) <= data1(2) xor data2(2) xor c(1);
c(2) <= (data1(2) and data2(2)) or (data1(2) and c(1)) or (data2(2) and c(1));
tmp(3) <= data1(3) xor data2(3) xor c(2);
if(data1(3) = data2(3)) then
c(3) <= (data1(3) and data2(3)) or (data1(3) and c(2)) or (data2(3) and c(2));
tmp(4) <= c(3);
tmp(5) <= c(3);
tmp(6) <= c(3);
tmp(7) <= c(3);
else
c(3) <= data1(3) xor data2(3) xor c(2);
tmp(4) <= c(3);
tmp(5) <= c(3);
tmp(6) <= c(3);
tmp(7) <= c(3);
end if;
else
tmp <= "ZZZZZZZZ";
end if;
end process sabiranje;
result <= tmp;
end Behavioral;
-----------------------------------------------------------------------------
entity mul is
Port (
clk : in STD_LOGIC;
pomnozi : in STD_LOGIC;
data1 : in STD_LOGIC_VECTOR (3 downto 0);
data2 : in STD_LOGIC_VECTOR (3 downto 0);
result : out STD_LOGIC_VECTOR (7 downto 0));
end mul;
architecture Behavioral of mul is
begin
mnozenje : process (clk,pomnozi)
begin
if (pomnozi='0') then
result <= std_logic_vector(signed(data1) * signed(data2));
else
result <= "ZZZZZZZZ";
end if;
end process mnozenje;
end Behavioral;
--------------------------------------------------------------------------
entity rotate is
Port ( clk : in STD_LOGIC;
rotiraj : in STD_LOGIC;
data1 : in STD_LOGIC_VECTOR (3 downto 0);
data2 : in STD_LOGIC_VECTOR (3 downto 0);
result : out STD_LOGIC_VECTOR (7 downto 0));
end rotate;
architecture Behavioral of rotate is
signal tmp : std_logic_vector (3 downto 0) := "0000";
signal tmp2 : std_logic_vector (7 downto 0) := "00000000";
begin
rotacija : process(clk,rotiraj)
begin
if (rotiraj='0') then
tmp <= std_logic_vector(rotate_left(unsigned(data1),to_integer(unsigned(data2))));
tmp2(0) <= tmp(0);
tmp2(1) <= tmp(1);
tmp2(2) <= tmp(2);
tmp2(3) <= tmp(3);
tmp2(4) <= '0';
tmp2(5) <= '0';
tmp2(6) <= '0';
tmp2(7) <= '0';
else
tmp2 <= "ZZZZZZZZ";
end if;
end process rotacija;
result <= tmp2;
end Behavioral;
--------------------------------------------------------------------------
-- Logic OR operation
entity logicko_ILI is
Port ( clk : in STD_LOGIC;
data1 : in STD_LOGIC_VECTOR (3 downto 0);
data2 : in STD_LOGIC_VECTOR (3 downto 0);
logili : in STD_LOGIC;
result : out STD_LOGIC_VECTOR (7 downto 0));
end logicko_ILI;
architecture Behavioral of logicko_ILI is
signal c : std_logic_vector (5 downto 0) := "000000";
signal tmp : std_logic_vector (7 downto 0) := "00000000";
begin
logicko : process(clk,logili)
begin
if (logili = '0') then
tmp(0) <= data1(0) or data2(0);
tmp(1) <= data1(1) or data2(1);
tmp(2) <= data1(2) or data2(2);
tmp(3) <= data1(3) or data2(3);
tmp(4) <= '0';
tmp(5) <= '1';
tmp(6) <= '1';
tmp(7) <= '1';
else
tmp <= "ZZZZZZZZ";
end if;
end process logicko;
result <= tmp;
end Behavioral;
I think you should even use your clk and reset signals in process. Your design is completely asynchron! This is a very bad idea.
A synchron process with asynchron reset look like this:
test : process (clk,reset)
begin
if (reset) then
c = 0;
elsif (rising_edge(clk)) then
c = a + b;
end if;
end process:
None of your sensitivity lists are correct. This does not comply with IEEE standard on syntesizable RTL. It poses a a high risk of getting synthesis results that are different from your simulation results.
line: 24 Incomplete sensitivity list. Missing signals: tmpm, tmps, tmpr, tmpi
line: 86 Incomplete sensitivity list. Missing signals: data1, data2, c
line: 137 Incomplete sensitivity list. Missing signals: data1, data2
line: 166 Incomplete sensitivity list. Missing signals: tmp, data1, data2
line: 205 Incomplete sensitivity list. Missing signals: data1, data2,
(line numbers might be slightly off because I had to add use/library clauses for ieee.std_logic_1164)
Please check your synthesis results for warnings, or use a VHDL code checker before your synthesize.
I want to make a FSM model of FIR, for that I need to write FIR calculation code line in FSM implementation.
Here is the actual and correct code for FIR
entity fir_4tap is
port( Clk : in std_logic; --clock signal
Clk_fast : in std_logic;
-- Xin : in signed(7 downto 0); --input signal
bit_in : in std_logic;
bit_out : out std_logic;
Yout : out signed(15 downto 0) --filter output
);
end fir_4tap;
architecture Behavioral of fir_4tap is
signal add_out3 : signed(15 downto 0) := (others => '0');
signal index : unsigned(2 downto 0) := (others =>'0');
signal counter : unsigned(3 downto 0) := (others => '0');
signal p : unsigned(1 downto 0) := (others => '0');
signal k : unsigned(1 downto 0) := (others => '0');
signal j : unsigned(1 downto 0) := (others => '0');
type array_signed is array(8 downto 0) of signed(7 downto 0);
signal z : array_signed := (others => "00000000");
type array_signed1 is array(3 downto 0) of signed(7 downto 0);
signal H : array_signed1 := (others => "00000000");
signal Xin : array_signed1 := (others => "00000000");
begin
z(0) <= to_signed(-3,8);
z(1) <= to_signed(1,8);
z(2) <= to_signed(0,8);
z(3) <= to_signed(-2,8);
z(4) <= to_signed(-1,8);
z(5) <= to_signed(4,8);
z(6) <= to_signed(-5,8);
z(7) <= to_signed(6,8);
z(8) <= to_signed(0,8);
H(0) <= to_signed(-2,8);
H(1) <= to_signed(-1,8);
H(2) <= to_signed(3,8);
H(3) <= to_signed(4,8);
process (clk)
begin
if (rising_edge(Clk)) then
index <= index +1;
if (index = "111") then
Xin(to_integer(p)) <= z(to_integer(counter)); k <= p;
p <= p + 1;
***-- This part of the code has problem, I want to write the line which is summing --up for add_out3 in a for loop.***
add_out3 <= (others => '0');
add_out3 <= Xin(to_integer(k))*H(to_integer(j)) + Xin(to_integer(k-1))*H(to_integer(j+1)) + Xin(to_integer(k-2))*H(to_integer(j+2)) + Xin(to_integer(k-3))*H(to_integer(j+3));
Yout <= add_out3;
end if;
end if;
end process;
end Behavioral;
Now Below is the FSM implementation try by me but not getting the same out sample as input can somebody tell me what could be the problem in the code?
----------------FSM implementation of the FIR filter ----------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity test is
port( Clk : in std_logic; --clock signal
Clk_fast : in std_logic;
bit_in : in std_logic;
bit_out : out std_logic;
Yout : out signed(15 downto 0) --filter output
);
end test;
architecture Behavioral of test is
signal data_buffer : signed(7 downto 0) := (others => '0');
signal index : unsigned(2 downto 0) := (others =>'0');
signal counter : unsigned(3 downto 0) := (others => '0');
type array_signed is array(8 downto 0) of signed(7 downto 0);
signal z : array_signed := (others => "00000000");
type array_signed1 is array(3 downto 0) of signed(7 downto 0);
signal H : array_signed1 := (others => "00000000");
signal input : signed(7 downto 0) := (others => '0');
type MULT_TYPE is array(3 downto 0) of signed(15 downto 0);
signal MULT_array : MULT_TYPE := (others => "0000000000000000");
type ADD_TYPE is array(3 downto 0) of signed(15 downto 0);
signal ADD_array : ADD_TYPE := (others => "0000000000000000");
constant ZERO : signed(15 downto 0) := (others => '0');
type state_type is (s0,s1,s2,s3); --type of state machine.
signal current_s : state_type := s0; --current and next state declaration.
signal next_s : state_type := s0;
signal reset : std_logic := '0';
signal go : std_logic := '0';
signal change_state : std_logic := '0' ;
signal counter_FSM_monitor : unsigned( 6 downto 0) := "0000000";
begin
z(0) <= to_signed(-3,8);
z(1) <= to_signed(1,8);
z(2) <= to_signed(0,8);
z(3) <= to_signed(-2,8);
z(4) <= to_signed(-1,8);
z(5) <= to_signed(4,8);
z(6) <= to_signed(-5,8);
z(7) <= to_signed(6,8);
z(8) <= to_signed(0,8);
H(0) <= to_signed(-2,8);
H(1) <= to_signed(-1,8);
H(2) <= to_signed(3,8);
H(3) <= to_signed(4,8);
process (Clk) is
begin
if falling_edge(Clk) then
data_buffer(to_integer(index)) <= bit_in;
index <= index +1;
if (index = "111") then
input <= z(to_integer(counter));
counter <= counter + 1;
if(counter = "1000") then
counter <= "0000";
end if;
end if;
end if;
end process;
process (clk_fast)
begin
if (falling_edge(clk_fast)) then
counter_FSM_monitor <= counter_FSM_monitor + 1;
if( to_integer(counter_FSM_monitor) = 76) then
counter_FSM_monitor <= "0000000";
end if;
case change_state is
when '1' =>
current_s <= next_s; --state change.
when '0' => --current_s <= s0;
when others =>
end case;
end if;
end process;
Process(current_s,input)
begin
if ( to_integer(counter_FSM_monitor) < 64 ) then
-- waiting for the Input
elsif (to_integer(counter_FSM_monitor) >= 64 and to_integer(counter_FSM_monitor) < 76) then
---------------------------------------------- FSM ----------------------------------------
case current_s is
when s0 =>
mult_array(0) <= input*H(3);
ADD_array(0) <= ZERO + mult_array(0);
next_s <= s1;
change_state <= '1';
when s1 =>
mult_array(1) <= input*H(2);
ADD_array(1) <= mult_array(1) + ADD_array(0);
next_s <= s2;
change_state <= '1';
when s2 =>
mult_array(2) <= input*H(1);
ADD_array(2) <= mult_array(2) + ADD_array(1);
next_s <= s3;
change_state <= '1';
when s3 =>
mult_array(3) <= input*H(0);
ADD_array(3) <= mult_array(3) + ADD_array(2);
Yout <= ADD_array(3);
next_s <= s0;
change_state <= '1';
when others =>
next_s <= s0;-- never comes here
change_state <= '1';
end case;
---------------------------------------------- FSM ----------------------------------------
end if;
end process;
end Behavioral;
How ever I am not able to receive the same output which I received by the first code.
FSM code gives the correct output for the first out but from the second out sample it gives wrong result.Can somebody tell me what I am doing wrong ?
This answer is for the initial version of the question but Now question has been changed.
Made add_out3 a variable instead of a signal.
for i in 0 to 3 loop
add_out3 := add_out3 + Xin(k-i)*H(i);
end loop;
Did the above changes in the for loop It works fine.
So the code in my question is a correct code for FIR also, works smoothly.
Learnt that one needs to be very careful while using signal or variables. All the signals get a new value at the same time i.e at the end of clock period, while in variables values gets updated as assigned within a process. Tried to run the simulation step by step and figured out the problem.