difference of two number from set of numbers input from file in VHDL - file-io
i am trying to find difference of two numbers from set of number available in file. "read.txt" contain numbers as
5
15
25
36
98
654
256
20
354
and i want output as 10 10 11 62 556 398 236 334
but i am getting in my output file "realout.txt" as 0
0
10
11
556
236
236
236
236
236
236
i don't know why every time at starting position 0 is printed and at the end number is repeated 5 times more..please help me to solve this problem my code is here.
library IEEE;
library std;
use ieee.std_logic_1164.all;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use ieee.numeric_std.all;
use IEEE.MATH_REAL.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.STD_LOGIC_TEXTIO.ALL;
use std.textio.all; --include package textio.vhd
entity testvhdl is
end testvhdl;
architecture Behavioral of testvhdl is
constant MAX : integer := 256*256-1;
SIGNAL rstb : std_logic := '0';
SIGNAL clk : std_logic := '0';
SIGNAL a : std_logic_vector(7 downto 0) := (others=>'0');
--Outputs
SIGNAL sum : std_logic_vector(7 downto 0);
--period of clock,bit for indicating end of file.
signal endoffile : bit := '0';
signal d1,d2,intt,n: integer:=0;
signal aa,ab,ac: integer:=0;
signal linenumber : integer:=1;
--signal dbus: std_logic_vector(7 downto 0) := x"00";
--------------------------------------------------------------------------------------------
function CONV_STDLV8bit_2INT(ARG: std_logic_vector (7 downto 0))
return integer is
variable int: integer:=0;
variable tmp: std_logic_vector(7 downto 0);
begin
int :=0;
tmp := ARG;
for i in 0 to 7 loop
if (tmp(i) ='1') then
int := int+(2**i);
else
int := int+0;
end if;
end loop;
return int;
end CONV_STDLV8bit_2INT;
--------------------------------------------------------------------------------------------
function CONV_INT2STDLV(ARG: INTEGER; SIZE: INTEGER)
return STD_LOGIC_VECTOR is
variable result: STD_LOGIC_VECTOR (SIZE-1 downto 0):=x"00";
variable temp: integer:= 0;
begin
temp := ARG;
for i in 0 to SIZE-1 loop
if ((temp mod 2) = 1) then
result(i) := '1';
else
result(i) := '0';
end if;
if temp > 0 then
temp := temp / 2;
elsif (temp > integer'low) then
temp := (temp - 1) / 2; -- simulate ASR
else
temp := temp / 2; -- simulate ASR
end if;
end loop;
return result;
end CONV_INT2STDLV;
--------------------------------------------------------------------------------------------
constant PERIOD : time := 20 ns;
constant DUTY_CYCLE : real := 0.5;
constant OFFSET : time := 30 ns;
begin
-- Instantiate the Unit Under Test (UUT)
--uut: imadder PORT MAP(
-- rstb => rstb,
-- clk => clk,
-- a => a,
-- b => b,
-- sum => sum
-- );
CLOCK: PROCESS -- clock process for clk
BEGIN
WAIT for OFFSET;
CLOCK_LOOP : LOOP
clk <= '0';
WAIT FOR (PERIOD - (PERIOD * DUTY_CYCLE));
clk <= '1';
WAIT FOR (PERIOD * DUTY_CYCLE);
END LOOP CLOCK_LOOP;
END PROCESS;
tb: PROCESS
BEGIN
rstb <='0';
wait for 60ns;
rstb <='1';
wait for 1312us; -- will wait forever
END PROCESS;
reading : process
file infile : text is in "real.txt"; --declare input file 1987
file outfile : text is out "realout.txt"; --declare output file 1987
--file infile2 : text is in "img2.txt"; --declare input file 1987
variable inline,inline2 : line; --line number declaration
variable dataread1 : integer;
variable dataread2 : integer;
variable buff_out : line; --line number declaration
-- variable aa,ab,ac: integer:=0;
begin
wait until clk = '0' and clk'event;
if(n < 10) then
if (not (endfile(infile))) then --checking the "END OF FILE" is not reached.
readline(infile, inline);
readline(infile, inline2);
read(inline, dataread1);
read(inline2, dataread2);
d1 <= dataread1;
d2 <= dataread2;
-- if n mod 5 = 0 then
aa <= abs(d1 - d2);
-- a <= CONV_INT2STDLV(aa,8);
--
-- n <= n+1;
-- elsif (d1 > aa) then
-- ab <= d1 - aa;
-- ac <= ac+ab;
-- aa <= d1;
--
-- else
-- ab <= aa - d1;
-- ac <= ac+ab;
-- aa <= d1;
--
-- end if;
-- d1 <= ac;
--readline(infile2, inline2);
--read(inline2, dataread1);
--d2 <=integer(dataread1);
--b <= CONV_INT2STDLV(d2,8);
else
a<=x"00";
--b<=x"00";
end if;
else
endoffile <='1'; --set signal to tell end of file read file is reached.
end if;
-- end process reading;
--write process #negative edge
--writing : process
-- begin
-- wait until clk = '0' and clk'event;
if(endoffile='0') then --if the file end is not reached.
--intt <= CONV_STDLV8bit_2INT(aa);
if(linenumber > 0) then
n <= n+1;
--if(linenumber>11) then
write(buff_out, aa);
writeline(outfile, buff_out);-- write line to output_image text file.
--end if;
end if;
linenumber <= linenumber + 1;
else
null;
end if;
end process reading;
end Behavioral;
--WRITE (buf, string'("hello"));
--WRITELINE(fileptr,buf);
--WRITE (buf, bit_vector'(" 010111 "));
--WRITELINE(fileptr,buf);
--http://myfpgablog.blogspot.in/2011/12/memory-initialization-methods.html
-- constant MEM_DEPTH : integer := 2**ADDR_WIDTH;
-- type mem_type is array (0 to MEM_DEPTH-1) of signed(DATA_WIDTH-1 downto 0);
-- impure function init_mem(mif_file_name : in string) return mem_type is
-- file mif_file : text open read_mode is mif_file_name;
-- variable mif_line : line;
-- variable temp_bv : bit_vector(DATA_WIDTH-1 downto 0);
-- variable temp_mem : mem_type;
-- begin
-- for i in mem_type'range loop
-- readline(mif_file, mif_line);
-- read(mif_line, temp_bv);
-- temp_mem(i) := signed(to_stdlogicvector(temp_bv));
-- end loop;
-- return temp_mem;
-- end function;
-- constant mem : mem_type := init_mem("mem_init_vhd.mif");
...i don't know why every time at starting position 0 is printed and at the end number is repeated 5 times more..please help me to solve this problem my code is here.
Besides the wild context clauses and all the extraneous noise there are two things observably wrong here. First you proposed input data set for real.txt has an odd number of lines (elements - integers). Second you are misapplying the BIT signal endofile:
reading :
process
file infile : text is in "real.txt";
file outfile : text is out "realout.txt";
variable inline,inline2 : line;
variable dataread1 : integer;
variable dataread2 : integer;
variable buff_out : line;
begin
wait until clk = '0' and clk'event;
if(n < 10) then
if (not (endfile(infile))) then
readline(infile, inline);
readline(infile, inline2);
read(inline, dataread1);
read(inline2, dataread2);
d1 <= dataread1;
d2 <= dataread2;
aa <= abs(d1 - d2);
else
a<=x"00";
end if;
else
endoffile <='1';
end if;
if(endoffile='0') then
if(linenumber > 0) then
n <= n+1;
write(buff_out, aa);
writeline(outfile, buff_out);
end if;
linenumber <= linenumber + 1;
else
null;
end if;
end process reading;
This is what your design with less than 20 integers on separate lines looks like:
As you can see from the waveform that results in the last value being repeated (the falling edge of the following clocks).
I added the 720 so it wouldn't get an integer read fail assertion.
The first two zeros are from not holding off output when rstb is true and a pipeline delay loading d0, d1 on a falling clock edge and then assigning aa on the next clock edge. There isn't a pipeline signal to qualify aa as valid for output.
endofile will never get written to a '1' where that assignment is unless your data set is big enough. n is counting input pairs of integers (pairs of lines):
So endofile should be fixed (on two counts, it's not set when an end of file condition is actually encountered, and the second readline is assumed to have been successful).
There's a third thing wrong, with enough data from real.txt you're missing the last absolute difference value in realout.txt, which says that pipeline signal specifying aa is valid should have a hold over as well as a hold off.
It might be easier to fix this by troubleshooting waveforms.
For the portion of your code not commented out the context clause should look like this:
library IEEE;
use ieee.std_logic_1164.all;
use std.textio.all;
Related
found '0' definitions of operator "**", cannot determine exact overloaded matching definition for "**" in VHDL
I am trying to simulate the below code. However, it shows the error " found '0' definitions of operator "", cannot determine exact overloaded matching definition for "" ". I have had attached the required packages to my code. please guide me with this error. Thank you in advance. library IEEE; USE IEEE.std_logic_1164.all; USE IEEE.numeric_std.all; USE IEEE.std_logic_arith.all; USE IEEE.math_real.all; library IEEE_proposed; use IEEE_proposed.fixed_pkg.all; entity test_zp is end; Architecture ARCHofZP of test_zp is TYPE matrix IS ARRAY ( NATURAL RANGE <>, NATURAL RANGE <> ) OF INTEGER RANGE 0 TO 500; SIGNAL kernel : matrix ( 1 TO 3 , 1 TO 3 ) := ((1,0,0),(0,1,0),(1,0,1)); SIGNAL image1 : matrix ( 1 To 6 , 1 TO 6 ) := ((25,100,75,49,130,15),(50,80,0,70,100,34),(20,5,10,20,30,0),(45,60,50,12,24,32),(34,37,53,55,21,90),(45,65,55,78,20,16)); FUNCTION batchnorm (outimg : matrix ( 1 To 8 , 1 TO 8 ) ) RETURN matrix IS VARIABLE sum1 : INTEGER RANGE 0 TO 500; VARIABLE SD1,SD,mean,ave,sum : UFIXED (10 downto -2):= "00000000"; VARIABLE batchnorm_mat : matrix (outimg'RANGE(1), outimg'RANGE(2)); CONSTANT alpha,beta : UFIXED (1 downto -2):= "0010"; BEGIN R1 : FOR i IN outimg'RANGE(1) LOOP C1 : FOR j IN outimg'RANGE(2) LOOP sum1 := sum1 + outimg(i,j); END LOOP; END LOOP; mean := sum1 / outimg'LENGTH; ave := to_ufixed(23,10,-2); R2 : FOR i IN outimg'RANGE(1) LOOP C2 : FOR j IN outimg'RANGE(2) LOOP SD1 := ((to_ufixed(outimg(i,j),10,-2)-ave)/to_ufixed(outimg'LENGTH,10,-2)) + SD1; END LOOP; END LOOP; SD := SD1 ** (2); R3 : FOR i IN batchnorm_mat'RANGE(1) LOOP C3 : FOR j IN batchnorm_mat'RANGE(2) LOOP batchnorm_mat(i,j) := ((to_ufixed(outimg(i,j),10,-2) - ave)/(SD)) * alpha + beta ; END LOOP; END LOOP; RETURN batchnorm_mat; -- return batch normalized outimg matrix named batchnorm_mat END FUNCTION batchnorm; begin outimg <= zero_padding( kernel , image1 ); end Architecture ARCHofZP;
errors while using two process in one entity vhdl
I am trying to write a signal generator with VHDL and state machine approach. it needs to have two processes in an entity and I am doing everything just as same as the course I've passed but I am getting some errors around my process and I think something must be wrong with it. this is the code entity pulse_generator is port(clk : in std_logic; output: out std_logic); end pulse_generator; architecture Behavioral of pulse_generator is type state is (one, two, three, four); signal nxt, pre: state; begin --upper p1: process(clk) begin if (falling_edge(clk))then pre <= nxt; end if end process p1; --lower p2: process(pre) variable count: integer range 0 to 500; begin case pre is when one => output <= '0'; count := count+1; if (count = 300)then nxt <= two; count := 0; else nxt <= one; end if; when two => output <= '1'; count := count+1; if (count = 400)then nxt <= three; count := 0; else nxt <= two; end if; when three => output <= '0'; count := count+1; if (count = 500)then nxt <= four; count := 0; else nxt <= three; end if; when four => output <= '1'; count := count+1; if (count = 200)then nxt <= one; count := 0; else nxt <= four; end if; end case; end process p2; end Behavioral; and these are the errors ERROR:HDLCompiler:806 - Line 19: Syntax error near "end". ERROR:HDLCompiler:806 - Line 22: Syntax error near "process". ERROR:HDLCompiler:806 - Line 23: Syntax error near "variable". ERROR:HDLCompiler:806 - Line 59: Syntax error near "process". ERROR:HDLCompiler:806 - Line 61: Syntax error near "Behavioral" what am I doing wrong?
VHDL Syntax error in user defined package RNG for genetic algorithm in line number 5
Library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; Type arr is array (1 to mut_bits) of integer; type chrom_matrix is array (1 to pop_size) of std_logic_vector(1 to n_comp); type fitness_arr is array (1 to pop_size) of integer range 0 to 1000; --type fitness_arr1 is array(1 to pop_size) of real; type adj_matrix is array (1 to n_comp,1 to n_comp) of bit; function evalfnc (signal chromosome: in std_logic_vector(1 to 8); signal cut_info:adj_matrix) return integer; procedure randg (variable x,y,t:in integer range 0 to 1000; variable z: out integer); procedure convert_bit(variable a:in integer;variable y:out std_logic_vector(8 downto 1)); end rng; package body rng is procedure randg (variable x,y,t:in integer range 0 to 1000; variable z: out integer) is variable val, a:integer range 0 to 1000:= 0; begin if x>y then a:= x-y; else a:= y-x; end if; if t > 3*a then val:= (t-a)/2; elsif t > a then val:= t-a; else val:= (x+y+t)/2; end if; z:= val; end randg; function evalfnc (signal chromosome: in std_logic_vector(1 to 8); signal cut_info:adj_matrix) return integer is variable fitness: integer range 0 to 500:= 0; variable cut_val: integer range 0 to 15:= 0; variable max_fit:integer range 0 to 360:=100; begin for i in 1 to n_comp loop for j in 1 to n_comp loop if cut_info(i,j)= ‘1’ then cut_val:= cut_val +1; end if; end loop; end loop; fitness := max_fit - cut_val; return fitness; end evalfnc; procedure convert_bit(variable a:in integer ; variable y:out std_logic_vector(8 downto 1)) is variable no:std_logic_vector(8 downto 1):=”00000000”; variable num: integer range 0 to 256; begin num:= a; if num <= 255 and num>= 128 then no(8):=’1’; num:=num - 128; end if; if num < 128 and num >= 64 then no(7):=’1’; num:=num - 64; end if; if num < 64 and num >= 32 then no(6):=’1’; num:=num −32; end if; if num < 32 and num >= 16 then no(5):=’1’; num:=num - 16; end if; if num < 16 and num >= 8 then no(4):=’1’; num:=num - 8; end if; if num < 8 and num >= 4 then no(3):=’1’; num:=num - 4; end if; if num < 4 and num >= 2 then no(2):=’1’; num:=num - 2; end if; if num < 2 then no(1):=’1’; end if; y:= no; end convert_bit; end rng;
Line 5 should read package rng is.
Pushing std_logic_vector to variable
I'm trying to push two std_logic_vectors to to the variables a and b in the function divide. Now, the problem is that the variable b won't be written. But variable a will be written, which is coded the same way as b. I received the following error message: used initial value expression for variable "b1" because variable was never assigned a value This is the function call: s_ratio <= divide((to_unsigned(0,N_CUM-4) & unsigned(hold_ratio(7 downto 4))) , (to_unsigned(0,N_CUM-4) & unsigned(hold_ratio(3 downto 0)))); And this is the function with the variable b in line 3. function divide (a : UNSIGNED; b : UNSIGNED) return UNSIGNED is variable a1 : unsigned(a'length-1 downto 0):=a; variable b1 : unsigned(b'length-1 downto 0):=b; variable p1 : unsigned(b'length downto 0):= (others => '0'); variable i : integer:=0; begin for i in 0 to b'length-1 loop p1(b'length-1 downto 1) := p1(b'length-2 downto 0); p1(0) := a1(a'length-1); a1(a'length-1 downto 1) := a1(a'length-2 downto 0); p1 := p1-b1; if(p1(b'length-1) ='1') then a1(0) :='0'; p1 := p1+b1; else a1(0) :='1'; end if; end loop; return a1; end divide;
VHDL Dynamic slicing using mathematical expression
Is there an easy way to implement the following line: DataTX(255-index*8 downto 248-index*8) <= encoded; index is an integer that could be in the range 0 to 31. DataTx is a STD_LOCIC_VECTOR(263 downto 0). Now it currently throws an error saying there are multiple drivers for DataTx(263) and DataTx(260), which isn't actually occurring in this line. Is there any way to write this line or implement it without have to do a massive if statement or case statement. Thanks in the advance. Edit: The line above is placed in a process. Meanwhile the other parts of DataTx are set outside the process as follows DataTX(263 downto 261) <= "000" when spi_mode=reading else "001" when spi_mode=writing else "011" when spi_mode=rxMode else "101" when spi_mode=txMode; DataTX(260 downto 256) <= SPI_register; Edit2: DataTX(263 downto 261) <= "000" when spi_mode=reading else "001" when spi_mode=writing else "011" when spi_mode=rxMode else "101" when spi_mode=txMode; DataTX(260 downto 256) <= SPI_register; -- Set the RF Chan based on input rf_chan <= RfChans(0) when base_selection="00" else RfChans(1) when base_selection="01" else RfChans(2) when base_selection="10" else RfChans(3) when base_selection="11"; -- Set the Base Address based on input base_addr <= Bases(0) when base_selection="00" else Bases(1) when base_selection="01" else Bases(2) when base_selection="10" else Bases(3) when base_selection="11"; process(clk) variable s_index : integer range 0 to 31 := 0; variable e_index : integer range 0 to 31 := 0; variable r_index : integer range 0 to 31 := 0; variable counter : integer range 0 to 7 := 0; begin if (rst = '1') then ... elsif (clk'event and clk='1') then case state is when setup => case setup_state is -- Some code like this is set here spi_mode <= writing; spi_register <= "10000"; DataTX(255 downto 224) <= base_addr; DataTX(223 downto 0) <= (others => '1'); -- Fill with FF when idle => ... -- nothing here of relevance -- Moves to E_setup when E_setup => -- DataTx set here spi_mode <= writing; spi_register <= "00000"; SPI_trigger <= '1'; state <= E_setupd; when E_setupd => -- one cycle delay SPI_Trigger <= '0'; if ((counter = 7) and SS='1') then -- Signals that SPI module has finished state <= E_encode; counter := 0; elsif (counter < 7) then -- Give it some time to start counter := counter +1; end if; when E_encode => encode_input <= SEQUENCE(e_index); e_index := e_index +1; state <= E_done; when E_done => spi_register <= "00000"; -- Error here DataTX(255-index*8 downto 248-index*8) <= encoded; if (e_index = 31) then e_index := 0; state <= E_send; else e_index := e_index +1; state <= E_encode; end if; end case; end if; end process;
The updated question gives enough information to attempt an answer. It comes down to what is "locally static" i.e. computable without actually executing the process, so that hardware can be synthesised to meet the specification. Now it might be obvious to you that DataTX(<arbitrary range expression>) <= encoded; only drives selected parts of DataTX leaving others undriven, without evaluating <arbitrary range expression>, but the synthesis tool isn't quite that smart. So the language places a restriction on the process, that the "locally static" expression is ALL of DataTX and so the process drives all of DataTX. (NOTE: had the range expression been purely in terms of constants or numeric literals,this restriction would not apply) The external assignments then form your additional drivers giving rise to "multiple drivers" errors. Two fixes : 1) Drive the entirety of DataTX within the process, i.e. move the other slice assignments within the process ... this looks like unclean design to me 2) Assign a new signal e.g. EncodedTX within the process, and externally assign it to the correct slice of DataTX DataTX(255 downto 0) <= EncodedTX; or better (clearer design intent) DataTX <= SPI_Mode_Bits & SPI_Register & Encoded_TX; with a suitable declaration and assignment for the SPI_Mode_Bits signal. Possibly there are other fixes too, but the second of these would probably be my first choice... Given Edit2 I now believe option (1) is cleaner : e.g. assigning the extra bits in the main state machine process, which is where you set up SPI_Mode and SPI_Register anyway. You can even make SPI_Register an alias for the relevant slice of Data_TX. Then you don't need to cross reference between the SM and the external cruft needed to support it. For example, consider the following declarations : alias SPI_Register : std_logic_vector(4 downto 0) is DataTX(260 downto 256); subtype SPI_Mode_Type is std_logic_vector(2 downto 0); alias SPI_Mode : SPI_Mode_Type is DataTX(263 downto 261); constant writing : SPI_Mode_Type := "001"; -- and a few more of these The state machine, without change, will now perform all the assignments to Datatx and the external assignments can simply be deleted.