I'm new to Stack Overflow and to VHDL too. I have completed the logic of an N-bit shifter and tested it using a testbench. But am unable to synthesize it.
While synthesizing I get an error saying "left and right bounds of a slice must be either constant or dynamic" (it is in line 37 and 45, also visible in the attached picture). Can somebody please tell what I need to fix (and perhaps how)?
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
use work.types.all;
use work.functions.all;
use work.casts.all;
entity logbarrel is
generic ( N : natural := 32
);
port ( a : in std_logic_vector(N-1 downto 0); -- input data word
func : in std_logic_vector( 2 downto 0); -- ctrl word (000=>>, 001=<<, 010=*>, 011=<*, 100=>>>)
shamt : in std_logic_vector(log2(N)-1 downto 0); -- shift amount
y : out std_logic_vector(N-1 downto 0) -- output data word
);
end;
architecture rtl1 of logbarrel is
begin
process(all)
constant stage : natural := log2(N); -- number of stages
variable rotr : arr_of_slv(stage-1 downto 0)(N-1 downto 0); -- rotated words
variable mask : arr_of_slv( N-1 downto 0)(N-1 downto 0); -- masks for all possible shifts
variable sh : std_logic_vector(shamt'range) := (others =>'0'); -- used as actual shift amount
begin
-- left or right shift
if to_int(func) = 1 OR to_int(func) = 3 then --checking for left, easier
sh := (others =>'0'); --left makes sh = 000
else
sh := (0 => '1', others =>'0'); --right makes sh = 001
end if;
-- 1st stage
if shamt(0) = '1' then -- shift if needed
rotr(stage-1) := a(N*(1-to_int(sh))+2*to_int(sh)-2 downto 0) & a(N-1 downto N*(1-to_int(sh))+2*to_int(sh)-2+1); --rotate
else
rotr(stage-1) := a; --no shift
end if;
-- i-th stage
for i in stage-2 downto 0 loop
if shamt(stage-i-1) = '1' then -- shift if needed
rotr(i) := rotr(i+1)(N*(1-to_int(sh))+(2*to_int(sh)-1)*2**(stage-i-1)-1 downto 0) & rotr(i+1)(N-1 downto N*(1-to_int(sh))+(2*to_int(sh)-1)*2**(stage-i-1)); --rotate
else
rotr(i) := rotr(i+1); --no shift at this level
end if;
end loop;
-- mask the rotated data if needed
for i in 0 to N-1 loop
case func is
when "000" | "100" => mask(i) := (N-1 downto N-1-i+1 => '0') & (N-i-1 downto 0 => '1'); -- right shift
when "001" => mask(i) := (N-1 downto i => '1') & (i-1 downto 0 => '0'); -- left shift
when "010" | "011" => mask(i) := (others => '1'); -- rotate
when others => mask(i) := (others => '0'); -- this case 101 should not occur
end case;
end loop;
-- output masking
y <= (N-1 downto N-to_int(shamt) => a(N-1)) & (rotr(0)(N-to_int(shamt)-1 downto 0) AND mask(to_int(shamt))(N-to_int(shamt)-1 downto 0)) when func = "100" else -- masking for arith. right shift
rotr(0) AND mask(to_int(shamt)); -- masking for all other cases
end process;
end;
Here's the original code skeleton, on which I had to change the lines only where TODO was written
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
use work.types.all;
use work.functions.all;
use work.casts.all;
entity logbarrel is
generic ( N : natural := 32
);
port ( a : in std_logic_vector(N-1 downto 0); -- input data word
func : in std_logic_vector( 2 downto 0); -- ctrl word (000=>>, 001=<<, 010=*>, 011=<*, 100=>>>)
shamt : in std_logic_vector(log2(N)-1 downto 0); -- shift amount
y : out std_logic_vector(N-1 downto 0) -- output data word
);
end;
architecture rtl1 of logbarrel is
begin
process(all)
constant stage : natural := log2(N); -- number of stages
variable rotr : arr_of_slv(stage-1 downto 0)(N-1 downto 0); -- rotated words
variable mask : arr_of_slv( N-1 downto 0)(N-1 downto 0); -- masks for all possible shifts
variable sh : std_logic_vector(shamt'range) := (others =>'0'); -- used as actual shift amount
begin
-- left or right shift
if TODO then
sh := TODO
else
sh := TODO
end if;
-- 1st stage
if TODO then -- shift if needed
rotr(stage-1) := TODO
else
rotr(stage-1) := TODO
end if;
-- i-th stage
for i in TODO loop
if TODO then -- shift if needed
rotr(i) := TODO
else
rotr(i) := TODO
end if;
end loop;
-- mask the rotated data if needed
for i in 0 to N-1 loop
case func is
when TODO => mask(i) := TODO -- right shift
when TODO => mask(i) := TODO -- left shift
when TODO => mask(i) := TODO -- rotate
when others => mask(i) := TODO -- this case 101 should not occur
end case;
end loop;
-- output masking
y <= TODO when TODO else -- masking for arith. right shift
TODO -- masking for all other cases
end process;
end;
And here is the testbench used to test this as an instantiation. (It also initializes another such entity, I'll paste its code below, in case you want it).
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.casts.all;
use work.functions.all;
entity shifter_tb is
generic( N : natural := 32;
ainit: natural := 16#72345678#);
end;
architecture test of shifter_tb is
signal a, y1, y2 : std_logic_vector(N-1 downto 0):= to_slv(ainit,N);
signal func : std_logic_vector( 2 downto 0);
signal shamt : std_logic_vector(log2(N)-1 downto 0);
begin
stimuli: process
begin
-- for i in 0 to 2**a'length-1 loop
-- a <= to_slv(i, a'length);
for j in 0 to 4 loop --2**func'length-1 loop
func <= to_slv(j, func'length);
for k in 0 to 2**shamt'length-1 loop
shamt <= to_slv(k, shamt'length);
wait for 10 ns;
case func is
when "000" => assert (y1 = y2)
report strs(y1) & strs(y2) & " = " &
str(a) & " >> " & strs(to_int(shamt)) & str(func) ;
when "001" => assert (y1 = y2)
report strs(y1) & str(y2) & " = " &
str(a) & " << " & strs(to_int(shamt)) & str(func) ;
when "010" => assert (y1 = y2)
report strs(y1) & str(y2) & " = " &
str(a) & " *> " & strs(to_int(shamt)) & str(func) ;
when "011" => assert (y1 = y2)
report strs(y1) & str(y2) & " = " &
str(a) & " <* " & strs(to_int(shamt)) & str(func) ;
when others => assert (y1 = y2)
report strs(y1) & str(y2) & " = " &
str(a) & " >>> " & strs(to_int(shamt)) & str(func) ;
end case;
end loop;
end loop;
--end loop;
wait;
end process;
shifter1_inst: entity work.shifter
generic map (N => N)
port map (a, func, shamt, y1);
shifter2_inst: entity work.logbarrel
generic map (N => N)
port map (a, func, shamt, y2);
end;
The other entity called shifter (the golden model):
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
use work.types.all;
use work.functions.all;
use work.casts.all;
entity shifter is
generic ( N : natural := 32
);
port ( a : in std_logic_vector(N-1 downto 0);
func : in std_logic_vector( 2 downto 0);
shamt : in std_logic_vector(log2(N)-1 downto 0);
y : out std_logic_vector(N-1 downto 0)
);
end;
architecture rtl of shifter is
begin
process(all)
variable rotr, rotl, ashr, lshr, lshl : arr_of_slv(N-1 downto 0)(N-1 downto 0);
begin
lshr(0) := a; lshl(0) := a; ashr(0) := a; rotr(0) := a; rotl(0) := a;
for i in 1 to N-1 loop
lshr(i) := (i-1 downto 0 => '0') & a(N-1 downto i);
lshl(i) := a((N-1)-i downto 0) & (i-1 downto 0 => '0');
ashr(i) := (i-1 downto 0 => a(N-1)) & a(N-1 downto i);
rotr(i) := a( i-1 downto 0) & a(N-1 downto i);
rotl(i) := a((N-1)-i downto 0) & a(N-1 downto N-i);
end loop;
y <= lshr(to_int(shamt)) when func = "000" else
lshl(to_int(shamt)) when func = "001" else
rotr(to_int(shamt)) when func = "010" else
rotl(to_int(shamt)) when func = "011" else
ashr(to_int(shamt));
end process;
end;
And finally the header files (not sure what they're called in the VHDL world) that are being used in the testbench and the instantiated architectures:
types:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package types is
constant width : integer := 32;
subtype byte is natural range 7 downto 0;
subtype logic is std_logic;
subtype byteT is std_logic_vector(byte);
subtype word is std_logic_vector(width-1 downto 0);
subtype uword is unsigned(width-1 downto 0);
subtype sword is signed (width-1 downto 0);
type arr_of_slv is array (natural range <>) of std_logic_vector;
type matrix is array (natural range <>, natural range <>) of std_logic;
end;
package body types is
end;
functions:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.casts.all;
use work.types.all;
package functions is
function log2 (a : natural) return natural;
function replicate(s : std_logic; n: integer) return std_logic_vector;
function decode(arg : std_logic_vector) return std_logic_vector;
function mux(sel, x : std_logic_vector) return std_logic;
function mux(sel : std_logic_vector; x : arr_of_slv) return std_logic_vector;
-- function mux(sel : std_logic_vector; x : arr_of_slv (0 TO M-1)(N-1 downto 0)) return std_logic_vector is
function reduce(Inputs : std_logic_vector ) return std_logic_vector;
--function reduction( Inputs : arr_of_slv ) return std_logic_vector;
end;
package body functions is
function log2 (a: natural) return natural IS
variable val : natural := a;
variable log : natural := 0;
begin
for i in a downto 0 loop
val := val / 2;
if val > 0 then
log := log + 1;
end if;
end loop;
return log;
end;
function replicate(s: std_logic; n: integer) return std_logic_vector is
variable r : std_logic_vector(n-1 downto 0);
begin
for i in 0 to n-1 loop
r(i) := s;
end loop;
return r;
end;
function decode (arg : std_logic_vector) return std_logic_vector is
variable res : std_logic_vector((2**arg'length)-1 downto 0);
begin
res(to_int(arg)) := '1';
return res;
end;
function mux( sel, x : std_logic_vector ) return std_logic is
begin
return x(to_int(sel));
end;
function mux( sel : std_logic_vector; x: arr_of_slv) return std_logic_vector is
begin
-- assert Inputs'length <= 2 ** sel'length
-- report "Inputs size: " & integer'image(Inputs'length) & " is too big for the select";
return x(to_int(sel));
end;
-- function mux(sel : std_logic_vector; x : arr_of_slv (0 TO M-1)(N-1 downto 0)) return std_logic_vector is
-- variable y : std_logic_vector(x(0)'length-1 downto 0);
-- begin
-- y := x(to_int(sel));
-- return y;
-- end;
function reduce( Inputs : std_logic_vector ) return std_logic_vector is
constant N : integer := Inputs'length;
variable inp : std_logic_vector(N-1 downto 0);
begin
inp := Inputs;
if(N = 4) then
return inp(1 downto 0) xor inp(3 downto 2);
else
return reduce(inp((N-1) downto N/2)) xor reduce(inp(((N/2)-1) downto 0));
end if;
end;
-- function reduction( Inputs: arr_of_slv ) return std_logic_vector is
-- constant N : integer := Inputs'length;
-- variable inp : arr_of_slv(N-1 downto 0, 12-1 downto 0);
-- begin
-- --return x"1234"; --Inputs(0);
-- inp := Inputs;
-- if N = 1 then
-- return inp(0);
-- elsif N > 1 then
-- return reduction(inp(N-1 downto N/2)) xor reduction(inp(N/2-1 downto 0));
-- end if;
-- end;
end;
casts:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package casts is
function to_int(arg: std_logic_vector) return natural;
function to_sint(arg: std_logic_vector) return natural;
function to_int(arg: unsigned) return natural;
function to_int(arg: signed) return natural;
function to_slv(arg: integer; bits: integer) return std_logic_vector;
function to_slv(arg: unsigned) return std_logic_vector;
function to_slv(arg: signed) return std_logic_vector;
function to_slv(arg: std_ulogic_vector) return std_logic_vector;
function to_sslv(arg: integer; bits: natural) return std_logic_vector;
function str(s: std_ulogic_vector) return string;
function str(s: integer) return string;
function strs(s: std_ulogic_vector) return string;
function strs(s: integer) return string;
function strs(s: std_logic) return string;
function str(s: std_logic) return character;
end;
package body casts is
subtype logic is std_logic;
type logic_vector is array (natural range <>) of std_logic;
function to_int (arg: std_logic_vector) return natural IS
begin
return to_integer(unsigned(arg));
end;
function to_sint (arg: std_logic_vector) return natural IS
variable x : signed(arg'range);
begin
x := signed(arg);
return to_integer(x);
end;
function to_int (arg: unsigned) return natural IS
begin
return to_integer(arg);
end;
function to_int (arg: signed) return natural IS
begin
return to_integer(arg);
end;
function to_slv(arg: integer; bits: integer) return std_logic_vector is
begin
return std_logic_vector(to_unsigned(arg,bits));
end;
function to_sslv(arg: integer; bits: natural) return std_logic_vector is
begin
return std_logic_vector(to_signed(arg,bits));
end;
function to_slv(arg: unsigned) return std_logic_vector IS
begin
return std_logic_vector(arg);
end;
function to_slv(arg: std_ulogic_vector) return std_logic_vector IS
begin
return to_stdlogicvector(arg);
end;
function to_slv(arg: signed) return std_logic_vector IS
begin
return std_logic_vector(arg);
end;
function chr2sl (ch: in character) return std_logic is
begin
case ch is
when 'U' | 'u' => return 'U';
when 'X' | 'x' => return 'X';
when '0' => return '0';
when '1' => return '1';
when 'Z' | 'z' => return 'Z';
when 'W' | 'w' => return 'W';
when 'L' | 'l' => return 'L';
when 'H' | 'h' => return 'H';
when '-' => return '-';
when OTHERS => assert false
report "Illegal Character found" & ch
severity error;
return 'U';
end case;
end;
function str2sl (s: string) return std_logic_vector is
variable vector: std_logic_vector(s'LEFT - 1 DOWNTO 0);
begin
for i in s'RANGE loop
vector(i-1) := chr2sl(s(i));
end loop;
return vector;
end;
function to_char(s: std_ulogic) return character is
begin
case s is
when 'X' => return 'X';
when '0' => return '0';
when '1' => return '1';
when 'Z' => return 'Z';
when 'U' => return 'U';
when 'W' => return 'W';
when 'L' => return 'L';
when 'H' => return 'H';
when '-' => return '-';
end case;
end;
function str(s: std_ulogic_vector) return string is
variable ret:string(1 to s'length);
variable K : integer:= 1;
begin
for J in s'range loop
ret(K) := to_char(s(J));
K := K + 1;
end loop;
return ret;
end;
function strs(s: std_ulogic_vector) return string is
begin
return str(s) & ' ';
end;
function str(s: std_logic) return character is
begin
return to_char(s);
end;
function strs(s: std_logic) return string is
begin
return str(s) & ' ';
end;
function to_nstring(s: natural) return string is
variable ret, iret : string(1 to 16);
variable k, j : integer;
variable s1, s2, s3: natural := 0;
begin
s1 := s;
ret(1) := '0';
k := 1;
while (s1 > 0 and K < 16) loop
s2 := s1 / 10;
s3 := s1 - (s2 * 10);
if (s3 = 0) then
ret(k) := '0';
elsif (s3 = 1) then
ret(k) := '1';
elsif (s3 = 2) then
ret(k) := '2';
elsif (s3 = 3) then
ret(k) := '3';
elsif (s3 = 4) then
ret(k) := '4';
elsif (s3 = 5) then
ret(k) := '5';
elsif (s3 = 6) then
ret(k) := '6';
elsif (s3 = 7) then
ret(k) := '7';
elsif (s3 = 8) then
ret(k) := '8';
elsif (s3 = 9) then
ret(k) := '9';
end if;
k := k + 1;
s1 := s2;
end loop;
if (k > 1) then
k := k-1;
end if;
J := 1;
while (k > 0) loop
iret(j) := ret(k);
k := k-1;
j := j+1;
end loop;
return iret;
end;
function str(s: integer) return string is
begin
if (s < 0) then
return "-" & to_nstring(-s);
else
return to_nstring(s);
end if;
end;
function strs(s: integer) return string is
begin
return str(s) & ' ';
end;
end;
I'm trying to write a stimulus reader for vhdl testbench. it needs to read a text command and two text operands delimited by whitespaces in a text file.
entity tb is
end entity;
architecture sim is tb of
begin
process
variable L : line;
file STIMFILE : test is in "stim.txt";
variable s1 : string;
variable s2 : string;
variable s3 : string;
begin
while not endfile(STIMFILE) loop
readline(STIMFILE, L);
s1 := strtok(L, "\n\t ");
s2 := strtok(0, "\n\t ");
s3 := strtok(0, "\n\t ");
if (strcmp(s1, "ADDXYZ") = '1') then
report "ADDXYZ " & s2 & " " & s3;
end if;
end loop;
end process;
end architecture;
How would I do this in VHDL?
so far i have a function for strcmp:
FUNCTION strcmp(s1: STRING; s2: STRING) --string compare
RETURN BOOLEAN IS
BEGIN
IF(s1'LENGTH /= s2'LENGTH) THEN
RETURN FALSE;
ELSE
FOR i IN s1'RANGE LOOP
IF(s1(i) /= s2(i)) THEN
RETURN FALSE;
END IF;
END LOOP;
RETURN TRUE;
END IF;
END; --function strcmp
library ieee;
use ieee.std_logic_1164.all;
use std.textio.all;
package pkg_fancy_strings is
-- Max Line length to tokenize
constant STRTOK_MAX : natural := 200;
procedure line2string(L: inout line; S: out string);
function is_space (c:character) return boolean;
function is_nul (c:character) return boolean;
-- structure to maintain state between strtok calls
type strtok_t is
record
str : string(1 to STRTOK_MAX); --input string
pos : natural; --input string iterator position
more : boolean; --call strtok_next until more equals false stop
tok : string(1 to STRTOK_MAX); --token string value
len : natural; --token string length
valid : boolean; --token string valid
error : natural; --token string had an error, ex: truncation
end record;
-- return string of length n padded with nul if less than n originally
function strpad(n: natural; x: string; rm_comment: boolean) return string;
-- Initialize strtok structure with unparsed string
function strtok_init(s : string) return strtok_t;
-- tokenize string in strtok buffer
function strtok_next(t: strtok_t) return strtok_t;
-- compare strings
function strcmpi(s1: string; s2: string) return boolean;
-- convert string into integer
function str2integer(s: string) return integer;
end package;
package body pkg_fancy_strings is
function is_space(c:character) return boolean is
begin
if (c = ' ') then
return true;
end if;
if (c <= character'val(13)) then
return true;
end if;
return false;
end function;
function is_nul(c:character) return boolean is
begin
if (c = character'val(0)) then
return true;
end if;
return false;
end function;
procedure line2string(L: inout line; S: out string) is
variable good :boolean;
variable ch :character;
variable str :string(1 to STRTOK_MAX);
variable i :integer := 1;
variable len :integer := 0;
begin
-- Zero Line Buffer
for i in 1 to str'length loop
str(i) := character'val(0);
end loop;
len := 1;
loop
read(L, ch, good);
if (good = false) then
exit;
end if;
str(len) := ch;
len := len + 1;
if (is_nul(ch)) then
exit;
end if;
if (len > str'length-1) then
exit;
end if;
end loop;
S := str;
end procedure;
-- return string of length n padded with nul if less than n originally
function strpad(n: natural; x: string; rm_comment: boolean)
return string is
variable r: string(1 to n);
variable stop: natural;
begin
for i in 1 to n loop
r(i) := character'val(0);
end loop;
stop := x'length;
if (stop >= n) then
stop := n-1;
end if;
for i in 1 to stop loop
-- ignore everything on line after '#'
if (x(i) = '#') then
exit;
end if;
r(i) := x(i);
end loop;
return r;
end function;
-- Initialize strtok structure with unparsed string
function strtok_init(
s : string
) return strtok_t is
variable t :strtok_t;
variable i :natural;
variable ch :character;
begin
t.str := strpad(STRTOK_MAX, s, true);
t.pos := 1;
t.more := true;
t.valid := false; --tok string not valid yet
t.error := 0;
return t;
end function;
-- tokenize string in strtok buffer
function strtok_next(
t: strtok_t
) return strtok_t is
variable ch :character := character'val(0);
variable i :natural := 0;
variable r :strtok_t;
begin
r := t;
-- Zero t.tok
r.len := 0;
for i in 1 to r.tok'length loop
r.tok(i) := character'val(0);
end loop;
-- Eat Spaces
loop
if (r.pos > r.str'length-1) then
r.valid := false;
r.more := false;
return r;
end if;
ch := r.str(r.pos);
if (is_nul(ch) = true) then
r.valid := false;
r.more := false;
return r;
end if;
if (is_space(ch) = false) then
exit;
else
r.pos := r.pos + 1;
end if;
end loop;
-- Save Token
i := 1;
loop
if (i > r.tok'length-1) then
r.valid := true;
r.more := true;
r.error := 1;
return r;
end if;
if ((r.pos > r.str'length) or is_nul(r.str(r.pos))) then
r.valid := (r.tok'length /= 0);
r.more := false;
r.error := 0;
return r;
end if;
ch := r.str(r.pos);
if (is_space(ch)) then
r.valid := true;
r.more := true;
r.error := 0;
return r;
else
r.tok(i) := ch;
r.len := i;
i := i + 1;
r.pos := r.pos + 1;
end if;
end loop;
-- shouldn't get here
r.error := 2;
r.valid := false;
r.more := false;
return r;
end function;
--string compare
function strcmpi(s1: string; s2: string)
return boolean is
variable max: natural := 0;
variable end_s1:boolean;
variable end_s2:boolean;
variable nul_s1:boolean;
variable nul_s2:boolean;
begin
if (s1'length >= s2'length) then max := s1'length; else max := s2'length; end if;
for i in 1 to max loop
end_s1 := (i > s1'length);
end_s2 := (i > s2'length);
if (end_s1 and end_s2) then return true; end if;
if (end_s1) then
nul_s2 := (s2(i) = character'val(0));
if (nul_s2) then return true; end if;
end if;
if (end_s2) then
nul_s1 := (s1(i) = character'val(0));
if (nul_s1) then return true; end if;
end if;
nul_s1 := (s1(i) = character'val(0));
nul_s2 := (s2(i) = character'val(0));
if (nul_s1 and nul_s2) then return true; end if;
if(s1(i) /= s2(i)) then
return false;
end if;
end loop;
return true;
end function;
-- read next whitespace delimited string
-- return string is terminated with null's
procedure read_string(L: inout Line; s: out string(1 to 80);
good: out boolean) is
variable c :character;
variable r :string(1 to 80);
variable i :natural;
begin
r := (others => character'val(0));
s := (others => character'val(0));
-- Skip WhiteSpace
loop
read(L, c, good);
report "c:" & character'image(c);
if (good = False) then
good := False;
return;
elsif ((c = ' ') or (c <= character'val(13)) ) then
next;
end if;
exit;
end loop;
-- Read Until Non-Whitespace
i := 1;
r(i) := c;
i := i+1;
loop
read(L, c, good);
if (good = false) then
s := r;
good := True;
return;
elsif ((c = ' ') or (c <= character'val(13)) ) then
s := r;
good := True;
return;
else
r(i) := c;
i := i + 1;
end if;
end loop;
end procedure;
end package body;
-- EXAMPLE OF FANCY STRINGS USAGE:
--
-- use work.pkg_fancy_strings.all;
--
-- entity tb is
-- end entity;
--
-- architecture rtl of tb is
-- begin
-- process
-- file stim_in :text open read_mode is "testcase1.txt";
-- variable L :line;
-- variable sbuf :string(1 to STRTOK_MAX);
-- variable slen :natural;
-- variable t :strtok_t;
-- begin
-- t := strtok_init(" mary had a little #lamb");
-- while(t.more) loop
-- t := strtok_next(t);
-- if (t.valid) then
-- report ">>" & t.tok(1 to t.len) & "<<";
-- end if;
-- end loop;
--
-- report "done." severity failure;
-- end process;
-- end architecture;
--
I am trying to write some VHDL to make a sign magnitude addition (overload +) without using any + in the code. Using Quartus 2 13.0 Cyclonce IV E EP4ce115F29C7
When I try to compile my current project, I get the stack trace:
which points me to this line:
variable sum:std_logic_vector(max downto 0);
I am not sure where I am going wrong, I have looked for material on this but couldn't really find anything.
Here is my code:
Library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
package SIGN_MAGNITUDE_ARITH is
constant word_size: positive := 32;
type SIGN_MAG is array(natural range <>) of std_logic;
function "+"(L:SIGN_MAG; R:SIGN_MAG;) return SIGN_MAG;
--function "-"(L: SIGN_MAG; R: SIGN_MAG;) return SIGN_MAG;
--function "*"(L: SIGN_MAG; R: SIGN_MAG;) return SIGN_MAG;
--procedure "/"(signal Z, D: in SIGN_MAG; signal Q,R: out SIGN_MAG);
end;
package body SIGN_MAGNITUDE_ARITH is
-- Sign Magnitude addition (overload "+")
function "+"(L: SIGN_MAG; R: SIGN_MAG;) return SIGN_MAG is
constant max = (MAX(R'length, L'length));
variable carry:std_logic:='0';
variable sum:std_logic_vector(max downto 0);
begin
if(L(L'length-1)='0') and (R(R'length-1)='0') then
for i in 0 to max - 2 loop
sum(i):= L(i) xor R(i) xor carry;
carry:=( L(i) and R(i) ) or ( L(i) and carry ) or ( R(i) and carry );
end loop;
sum(max-1):=carry;
sum(max):='0';
end if;
return sum;
end;
end;
I'm learning PL/SQL and I can not find the error
si alguien me pudiese ayudar se lo agradeceria
ORA-06550: line 52, column 5: PLS-00103: Encountered the symbol "END"
when expecting one of the following:
& = - + ; < / > at in is mod remainder not rem <> or != or ~= >= <= <> and or like like2 like4 likec between
|| member submultiset The symbol ";" was substituted for "END" to
continue.
This is the code:
DECLARE
N_SUC NUMBER;
N_CLIENTE NUMBER;
N_TVENTA NUMBER;
N_FECHA DATE;
I_CLIENTE NUMBER;
I_TVENTA NUMBER;
begin
N_SUC := 1;
N_CLIENTE :=1;
N_TVENTA :=1;
I_CLIENTE :=1;
I_TVENTA := 1;
for loop_one in 1..4
loop
FOR LOOP_two IN 1..25
LOOP
IF N_TVENTA > 75 THEN
I_TVENTA:= I_TVENTA + 1;
END IF;
if N_CLIENTE <=10 then
I_CLIENTE:= 1;
elsif N_CLIENTE >10 AND N_CLIENTE <= 20 then
I_CLIENTE:= 2;
elsif N_CLIENTE>20 AND N_CLIENTE <= 30 THEN
I_CLIENTE:= 3;
elsif N_CLIENTE>30 AND N_CLIENTE <= 40 then
I_CLIENTE:= 4;
elsif N_CLIENTE>40 AND N_CLIENTE <= 50 then
I_CLIENTE:= 5;
elsif N_CLIENTE>50 AND N_CLIENTE <= 60 then
I_CLIENTE:= 6;
elsif N_CLIENTE>60 AND N_CLIENTE <= 70 then
I_CLIENTE:= 7;
elsif N_CLIENTE>70 AND N_CLIENTE <= 80 then
I_CLIENTE:= 8;
elsif N_CLIENTE>80 AND N_CLIENTE <= 90 then
I_CLIENTE:= 9;
elsif N_CLIENTE>90 AND N_CLIENTE <= 100 then
I_CLIENTE:= 10;
end if;
SELECT SYSDATE into N_FECHA FROM dual;
INSERT INTO marcos.VENTA
VALUES(SEQ_VENTA.nextval, 0, N_FECHA|| '-'||SEQ_VENTA, N_SUC, I_CLIENTE, I_TVENTA);
N_CLIENTE:= N_CLIENTE+1;
N_TVENTA:=N_TVENTA+1
END LOOP;
N_SUC := N_SUC+ 1;
end loop ;
commit;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('Se ha producido un error') ;
rollback;
end;
You miss a line terminator (semi-colon) in line 51, here:
N_TVENTA:=N_TVENTA+1
Hi I am having problem to display a static image using handel-c create a test pattern through the DE2-115 VGA.
For some reason I can't output the image to the monitor.
This is my tpad.hcc code:
#include "tpad.hch"
macro proc lcd_driver( lcd ) {
unsigned 24 colour;
unsigned 1 de;
interface bus_out() tpad_RGB( unsigned 24 clr = colour )
//Post pin for RGB color
//with {data = {"V27","U28","U27","R28","R27","V26",
//"T22","T21","R23","R22","R21","P21",
//"J26","L28","V25","V22","U22","V28"},
with {data = {"D12","D11","C12","A11","B11","C11","A10","B10", //BLUE
"C9","F10","B8","C8","H12","F8","G11","G8", //GREEN
"H10","H8","J12","G10","F12","D10","E11","E12"}, //RED
standard = "LVCMOS33"};
interface bus_out() tpad_control( unsigned 3 ctrl = (!__clock) # 1 #de)
with {data = {"C13","F11","A12", "G13","C10"},
standard = "LVCMOS33"};
//VHDL driver
//entity vga_controller is
//port (
// pixel_clk : IN STD_LOGIC; --pixel clock at frequency of VGA mode being used
// reset_n : IN STD_LOGIC; --active low asycnchronous reset
// h_sync : OUT STD_LOGIC; --horiztonal sync pulse
// v_sync : OUT STD_LOGIC; --vertical sync pulse
// disp_ena : OUT STD_LOGIC; --display enable ('1' = display time, '0' = blanking time)
// column : OUT INTEGER; --horizontal pixel coordinate
// row : OUT INTEGER; --vertical pixel coordinate
// n_blank : OUT STD_LOGIC; --direct blacking output to DAC
// n_sync : OUT STD_LOGIC --sync-on-green output to DAC
// );
//END vga_controller;
interface vga_controller( unsigned 11 row, unsigned 11 column, unsigned 1 disp_ena,
unsigned 1 h_sync, unsigned 1 v_sync, unsigned 1 n_sync,
unsigned 1 n_blank)
tpad_lcd( unsigned 1 pixel_clk = __clock, unsigned 1 reset_n = 0)
with {busformat = "B[I]"};
do par {
colour = lcd.r # lcd.g # lcd.b; // Synchronise LCD output signals
//de = !lcd.nb;
de = 1;
lcd.x = tpad_lcd.row;
lcd.y = tpad_lcd.column;
lcd.hs = tpad_lcd.h_sync;
lcd.vs = tpad_lcd.v_sync;
lcd.ns = tpad_lcd.n_sync;
lcd.nb = tpad_lcd.n_blank;
lcd.de = 1;
} while (1);
}
my tpad.hch:
typedef struct {
signal unsigned 11 x, y; // Position on display
signal unsigned 8 r, g, b; // Colour to display
signal unsigned 1 hs, vs, ns, nb, de; // syncronisation signals
} lcd_data;
macro proc lcd_driver( lcd );
This is my demo.hcc:
#include "tpad.hch"
set family = AlteraCycloneIII; /* Really a Cyclone IV */
set part = "EP4CE115F29C7";
interface bus_in (unsigned 1 pin) clock_pin () with {data = {"Y2"}};
interface altpll (unsigned 5 clk with {clockport = 1})
pll (unsigned 2 inclk = 0 # clock_pin.pin)
with {
busformat = "B[N:0]",
properties = {
{"bandwidth_type", "AUTO"},
{"clk0_divide_by", "5"},
{"clk0_duty_cycle", "50"},
{"clk0_multiply_by", "4"},
{"clk0_phase_shift", "0"},
{"compensate_clock", "CLK0"},
{"inclk0_input_frequency", "20000"},
{"intended_device_family", "Cyclone IV E"},
{"lpm_hint", "CBX_MODULE_PREFIX=pll"},
{"lpm_type", "altpll"},
{"operation_mode", "NORMAL"},
{"pll_type", "AUTO"},
{"port_clk0", "PORT_USED"},
{"width_clock", "5"}},
bind = 1};
set clock = internal pll.clk[0];
void main( void ) {
lcd_data lcd;
par {
lcd_driver( lcd );
do par {
lcd.r = lcd.x[7:0]; // Generate a simple test pattern
lcd.g = lcd.y[7:0];
lcd.b = (lcd.x + lcd.y)[9:2];
} while (1);
}
}
This is my VHDL code:
--------------------------------------------------------------------------------
--
-- FileName: vga_controller.vhd
-- Dependencies: none
-- Design Software: Quartus II 64-bit Version 12.1 Build 177 SJ Full Version
--
-- HDL CODE IS PROVIDED "AS IS." DIGI-KEY EXPRESSLY DISCLAIMS ANY
-- WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING BUT NOT
-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-- PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL DIGI-KEY
-- BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL
-- DAMAGES, LOST PROFITS OR LOST DATA, HARM TO YOUR EQUIPMENT, COST OF
-- PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
-- BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF),
-- ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER SIMILAR COSTS.
--
-- Version History
-- Version 1.0 05/10/2013 Scott Larson
-- Initial Public Release
--
--------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
ENTITY vga_controller IS
GENERIC(
h_pulse : INTEGER := 128; --horiztonal sync pulse width in pixels
h_bp : INTEGER := 88; --horiztonal back porch width in pixels
h_pixels : INTEGER := 800; --horiztonal display width in pixels
h_fp : INTEGER := 40; --horiztonal front porch width in pixels
h_pol : STD_LOGIC := '1'; --horizontal sync pulse polarity (1 = positive, 0 = negative)
v_pulse : INTEGER := 4; --vertical sync pulse width in rows
v_bp : INTEGER := 23; --vertical back porch width in rows
v_pixels : INTEGER := 600; --vertical display width in rows
v_fp : INTEGER := 1; --vertical front porch width in rows
v_pol : STD_LOGIC := '1'); --vertical sync pulse polarity (1 = positive, 0 = negative)
PORT(
pixel_clk : IN STD_LOGIC; --pixel clock at frequency of VGA mode being used
reset_n : IN STD_LOGIC; --active low asycnchronous reset
h_sync : OUT STD_LOGIC; --horiztonal sync pulse
v_sync : OUT STD_LOGIC; --vertical sync pulse
disp_ena : OUT STD_LOGIC; --display enable ('1' = display time, '0' = blanking time)
column : OUT STD_LOGIC_vector (10 downto 0); --horizontal pixel coordinate
row : OUT STD_LOGIC_vector (10 downto 0); --vertical pixel coordinate
n_blank : OUT STD_LOGIC; --direct blacking output to DAC
n_sync : OUT STD_LOGIC); --sync-on-green output to DAC
END vga_controller;
ARCHITECTURE behavior OF vga_controller IS
CONSTANT h_period : INTEGER := h_pulse + h_bp + h_pixels + h_fp; --total number of pixel clocks in a row
CONSTANT v_period : INTEGER := v_pulse + v_bp + v_pixels + v_fp; --total number of rows in column
BEGIN
n_blank <= '1'; --no direct blanking
n_sync <= '0'; --no sync on green
PROCESS(pixel_clk, reset_n)
VARIABLE h_count : INTEGER RANGE 0 TO h_period - 1 := 0; --horizontal counter (counts the columns)
VARIABLE v_count : INTEGER RANGE 0 TO v_period - 1 := 0; --vertical counter (counts the rows)
--VARIABLE h_count : unsigned (7 downto 0) := "00000000";
--VARIABLE v_count : unsigned (7 downto 0) := "00000000";
BEGIN
IF(reset_n = '0') THEN --reset asserted
h_count := 0; --reset horizontal counter
v_count := 0; --reset vertical counter
h_sync <= NOT h_pol; --deassert horizontal sync
v_sync <= NOT v_pol; --deassert vertical sync
disp_ena <= '0'; --disable display
column <= "00000000000"; --reset column pixel coordinate
row <= "00000000000"; --reset row pixel coordinate
ELSIF(pixel_clk'EVENT AND pixel_clk = '1') THEN
--counters
IF(h_count < h_period - 1) THEN --horizontal counter (pixels)
h_count := h_count + 1;
ELSE
h_count := 0;
IF(v_count < v_period - 1) THEN --veritcal counter (rows)
v_count := v_count + 1;
ELSE
v_count := 0;
END IF;
END IF;
--horizontal sync signal
IF(h_count < h_pixels + h_fp OR h_count > h_pixels + h_fp + h_pulse) THEN
h_sync <= NOT h_pol; --deassert horiztonal sync pulse
ELSE
h_sync <= h_pol; --assert horiztonal sync pulse
END IF;
--vertical sync signal
IF(v_count < v_pixels + v_fp OR v_count > v_pixels + v_fp + v_pulse) THEN
v_sync <= NOT v_pol; --deassert vertical sync pulse
ELSE
v_sync <= v_pol; --assert vertical sync pulse
END IF;
--set pixel coordinates
IF(h_count < h_pixels) THEN --horiztonal display time
--column <= h_count; --set horiztonal pixel coordinate
column <= std_logic_vector(to_unsigned(h_count, column'length)); --set horiztonal pixel coordinate
END IF;
IF(v_count < v_pixels) THEN --vertical display time
--row <= v_count; --set vertical pixel coordinate
row <= std_logic_vector(to_unsigned(v_count, column'length)); --set vertical pixel coordinate
END IF;
--set display enable output
IF(h_count < h_pixels AND v_count < v_pixels) THEN --display time
disp_ena <= '1'; --enable display
ELSE --blanking time
disp_ena <= '0'; --disable display
END IF;
END IF;
END PROCESS;
END behavior;