Related
I'm trying to assign the value of the output of a multiplexer to a signal, but I can't find the way to do it.
This is the code of the library work.
entity mux4a1 is
port(enable: in std_logic;
x: in std_logic_vector(3 downto 0);
sel: in std_logic_vector(1 downto 0);
y: out std_logic);
end mux4a1;
architecture funcional of mux4a1 is
begin
process(enable, x, sel)
begin
if enable = '0' then
y <= '0';
else
case sel is
when "00" => y <= x(0);
when "01" => y <= x(1);
when "10" => y <= x(2);
when others => y <= x(3);
end case;
end if;
end process;
end funcional;
This is my code:
entity practica1 is
port (x: in std_logic_vector(3 downto 0);
z: out std_logic_vector(3 downto 0));
end practica1;
architecture apartadoE of practica1 is
signal e: std_logic:= '1';
signal i: std_logic_vector (3 downto 0);
signal sel: std_logic_vector (1 downto 0);
begin
z(0) <= '0';
z(2) <= '0';
z(3) <= '0';
i(0) <= x(3) and x(1);
i(1) <= (not x(1)) and (not x(3));
i(2) <= x(1);
i(3) <= not x(1);
-- here is the problem, i donĀ“t how to assign it.
z(1) <= mux: entity work.mux4a1 port map (e, i, sel);
end apartadoE;
i finished creating a design in vhdl, of the algorithm sha256.
now im trying to get my design level higher by understanding how to change the code so i will get higher result of power, performance and area. the end game goal is trying to get the best netlist in my designs so i can get them into a chip.
so for my design: i got max frequency of 85 mhz in cyclone 4 FPGA with the usage of 8,500 total logic elements, 55% of the FPGA.
the main issue that i think made my design so big is that i wrote the code in a hierarchy manner, a lot of "elsif" and variables. and one other thing that could be better, i think, is if the quartus would implement my memory design as a memory and not with logic element, even that its only array of 16 words of 32 bits.
what you guys think i can improve ?
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
USE ieee.numeric_std.ALL;
entity padding is
port( clk : in std_logic;
rst : in std_logic;
ward : in std_logic_vector(31 downto 0);
ready : out std_logic;
hash : out std_logic_vector(255 downto 0));
end;
architecture padding of padding is
component sha256
port ( clk : in std_logic;
rst : in std_logic;
enable : in std_logic;
ward : in std_logic_vector(31 downto 0);
k : in std_logic_vector(31 downto 0);
h0 : in std_logic_vector(31 downto 0);
h1 : in std_logic_vector(31 downto 0);
h2 : in std_logic_vector(31 downto 0);
h3 : in std_logic_vector(31 downto 0);
h4 : in std_logic_vector(31 downto 0);
h5 : in std_logic_vector(31 downto 0);
h6 : in std_logic_vector(31 downto 0);
h7 : in std_logic_vector(31 downto 0);
ready : out std_logic;
digest : out std_logic_vector(255 downto 0));
end component;
type kconst is array ( 0 to 63 ) of std_logic_vector(31 downto 0);
type mem is array ( 0 to 15 ) of std_logic_vector(31 downto 0);
signal k : kconst := (x"428a2f98", x"71374491", x"b5c0fbcf", x"e9b5dba5", x"3956c25b", x"59f111f1", x"923f82a4", x"ab1c5ed5",
x"d807aa98", x"12835b01", x"243185be", x"550c7dc3", x"72be5d74", x"80deb1fe", x"9bdc06a7", x"c19bf174",
x"e49b69c1", x"efbe4786", x"0fc19dc6", x"240ca1cc", x"2de92c6f", x"4a7484aa", x"5cb0a9dc", x"76f988da",
x"983e5152", x"a831c66d", x"b00327c8", x"bf597fc7", x"c6e00bf3", x"d5a79147", x"06ca6351", x"14292967",
x"27b70a85", x"2e1b2138", x"4d2c6dfc", x"53380d13", x"650a7354", x"766a0abb", x"81c2c92e", x"92722c85",
x"a2bfe8a1", x"a81a664b", x"c24b8b70", x"c76c51a3", x"d192e819", x"d6990624", x"f40e3585", x"106aa070",
x"19a4c116", x"1e376c08", x"2748774c", x"34b0bcb5", x"391c0cb3", x"4ed8aa4a", x"5b9cca4f", x"682e6ff3",
x"748f82ee", x"78a5636f", x"84c87814", x"8cc70208", x"90befffa", x"a4506ceb", x"bef9a3f7", x"c67178f2");
signal first_mem : mem:= ( x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000",
x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000");
signal second_mem : mem:= ( x"00000000", x"00000000", x"00000000", x"00000000", x"80000000", x"00000000", x"00000000", x"00000000",
x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000280");
signal enable : std_logic;
signal enable1 : std_logic;
signal enable2 : std_logic;
signal r_d : std_logic;
signal k_in : std_logic_vector(31 downto 0);
signal ward_in : std_logic_vector(31 downto 0);
signal ward_in1 : std_logic_vector(31 downto 0);
signal ward_in2 : std_logic_vector(31 downto 0);
signal h0,h1,h2,h3 : std_logic_vector(31 downto 0);
signal h4,h5,h6,h7 : std_logic_vector(31 downto 0);
signal temp : std_logic_vector(255 downto 0);
signal temp1 : std_logic_vector(255 downto 0);
signal gama0 : std_logic_vector(31 downto 0);
signal gama1 : std_logic_vector(31 downto 0);
signal gama2 : std_logic_vector(31 downto 0);
signal gama3 : std_logic_vector(31 downto 0);
signal gama4 : std_logic_vector(31 downto 0);
signal gama5 : std_logic_vector(31 downto 0);
begin
sha1: sha256 port map(
clk ,
rst ,
enable ,
ward_in ,
k_in ,
h0 ,
h1 ,
h2 ,
h3 ,
h4 ,
h5 ,
h6 ,
h7 ,
enable1 ,
temp );
sha2: sha256 port map(
clk ,
rst ,
enable1 ,
ward_in1 ,
k_in ,
temp(255 downto 224),
temp(223 downto 192),
temp(191 downto 160),
temp(159 downto 128),
temp(127 downto 96 ),
temp(95 downto 64 ),
temp(63 downto 32 ),
temp(31 downto 0 ),
enable2 ,
temp1 );
sha3: sha256 port map(
clk ,
rst ,
r_d ,
ward_in2 ,
k_in ,
h0 ,
h1 ,
h2 ,
h3 ,
h4 ,
h5 ,
h6 ,
h7 ,
ready ,
hash );
h0 <= x"6a09e667";
h1 <= x"bb67ae85";
h2 <= x"3c6ef372";
h3 <= x"a54ff53a";
h4 <= x"510e527f";
h5 <= x"9b05688c";
h6 <= x"1f83d9ab";
h7 <= x"5be0cd19";
process (clk,rst)
variable i : integer;
variable j : integer;
variable m : integer;
variable n : integer;
variable l : integer;
begin
if rst = '0' then
enable <= '0';
i := 0;
j := 0;
m := 9;
n := 15;
l := 8;
elsif clk'event and clk = '1' then
if j = 16 then
j := 0;
end if;
if m = 16 then
m := 0;
end if;
if n = 16 then
n := 0;
end if;
if l = 16 then
l := 0;
end if;
if i = 193 then
i := 0;
elsif i > 144 then
first_mem(n) <= gama4 + first_mem(l) + gama5 + first_mem(n);
ward_in2 <= gama4 + first_mem(l) + gama5 + first_mem(n);
k_in <= k(i-129);
elsif i > 136 then
ward_in2 <= first_mem(n);
k_in <= k(i-129);
elsif i = 136 then
first_mem(n) <= temp1(31 downto 0);
ward_in2 <= temp1(31 downto 0);
k_in <= k(i-129);
elsif i = 135 then
first_mem(n) <= temp1(63 downto 32);
ward_in2 <= temp1(63 downto 32);
k_in <= k(i-129);
elsif i = 134 then
first_mem(n) <= temp1(95 downto 64);
ward_in2 <= temp1(95 downto 64);
k_in <= k(i-129);
elsif i = 133 then
first_mem(n) <= temp1(127 downto 96);
ward_in2 <= temp1(127 downto 96);
k_in <= k(i-129);
elsif i = 132 then
first_mem(n) <= temp1(159 downto 128);
ward_in2 <= temp1(159 downto 128);
k_in <= k(i-129);
elsif i = 131 then
first_mem(n) <= temp1(191 downto 160);
ward_in2 <= temp1(191 downto 160);
k_in <= k(i-129);
elsif i = 130 then
first_mem(n) <= temp1(223 downto 192);
ward_in2 <= temp1(223 downto 192);
k_in <= k(i-129);
elsif i = 129 then
first_mem(15) <= x"00000100";
first_mem(14) <= x"00000000";
first_mem(13) <= x"00000000";
first_mem(12) <= x"00000000";
first_mem(11) <= x"00000000";
first_mem(10) <= x"00000000";
first_mem(9) <= x"00000000";
first_mem(8) <= x"80000000";
first_mem(n) <= temp1(255 downto 224);
ward_in2 <= temp1(255 downto 224);
k_in <= k(i-129);
elsif i = 128 then
elsif i > 79 then
second_mem(j) <= gama2 + second_mem(m) + gama3 + second_mem(j);
ward_in1 <= gama2 + second_mem(m) + gama3 + second_mem(j);
k_in <= k(i-64);
elsif i > 63 then
enable <= '0';
ward_in1 <= second_mem(j);
k_in <= k(i-64);
elsif i > 19 then
first_mem(j) <= gama0 + first_mem(m) + gama1 + first_mem(j);
ward_in <= gama0 + first_mem(m) + gama1 + first_mem(j);
k_in <= k(i);
enable <= '1';
elsif i > 15 then
second_mem(j)<= ward;
first_mem(j) <= gama0 + first_mem(m) + gama1 + first_mem(j);
ward_in <= gama0 + first_mem(m) + gama1 + first_mem(j);
k_in <= k(i);
enable <= '1';
elsif i >= 0 then
first_mem(i) <= ward;
ward_in <= ward;
k_in <= k(i);
enable <= '1';
end if;
i := i + 1;
j := j + 1;
m := m + 1;
n := n + 1;
l := l + 1;
end if;
end process;
process (clk, rst)
begin
if rst = '0' then
r_d <= '0';
elsif clk'event and clk = '1' then
r_d <= enable2;
end if;
end process;
process (clk, rst)
variable f: integer;
variable j: integer;
variable l: integer;
variable m: integer;
begin
if rst = '0' then
f := 2;
j := 15;
l := 1;
m := 14;
elsif clk'event and clk = '1' then
if j = 16 then
j := 0;
end if;
if f = 16 then
f := 0;
end if;
if l = 16 then
l := 0;
end if;
if m = 16 then
m := 0;
end if;
gama0 <= ((first_mem(f)(6 downto 0) & first_mem(f)(31 downto 7)) xor (first_mem(f)(17 downto 0) & first_mem(f)(31 downto 18)) xor ("000" & first_mem(f)(31 downto 3)));
gama1 <= ((first_mem(j)(16 downto 0) & first_mem(j)(31 downto 17)) xor (first_mem(j)(18 downto 0) & first_mem(j)(31 downto 19)) xor ("0000000000" & first_mem(j)(31 downto 10)));
gama4 <= ((first_mem(l)(6 downto 0) & first_mem(l)(31 downto 7)) xor (first_mem(l)(17 downto 0) & first_mem(l)(31 downto 18)) xor ("000" & first_mem(l)(31 downto 3)));
gama5 <= ((first_mem(m)(16 downto 0) & first_mem(m)(31 downto 17)) xor (first_mem(m)(18 downto 0) & first_mem(m)(31 downto 19)) xor ("0000000000" & first_mem(m)(31 downto 10)));
gama2 <= ((second_mem(f)(6 downto 0) & second_mem(f)(31 downto 7)) xor (second_mem(f)(17 downto 0) & second_mem(f)(31 downto 18)) xor ("000" & second_mem(f)(31 downto 3)));
gama3 <= ((second_mem(j)(16 downto 0) & second_mem(j)(31 downto 17)) xor (second_mem(j)(18 downto 0) & second_mem(j)(31 downto 19)) xor ("0000000000" & second_mem(j)(31 downto 10)));
f := f + 1;
j := j + 1;
l := l + 1;
m := m + 1;
end if;
end process;
end;
elsif, i.e. "priority en/decoding", will effect the frequency of your design. With all the available logic resources you have left, you might consider a case statement... unless you actually have a need for priority en/decoding. Even then, if you can afford latency trade-offs you can do the decoding in several clock cycles (pipeline the decode) and your design will likely increase frequency... ultimately, you need to run a timing report and look at the slow paths to understand the bottlenecks.
If you really want to use RAM instead of FFs, you could infer a RAM (create an array), or if that doesn't work for you, you could then manually instantiate a device-specific RAM.... and, then, of course, add the control logic for it. if primitive, blackbox it to swap later for "same" ASIC library primitive
As far as "variables", the discussion is the same as "VHDL" vs. "Verilog", or "synch" vs "asynch" resets, mostly just opinions, and mine is, "I am not a fan of variables in synthesizable RTL"... they are legal for synthesis, but they "disappear" during syn, so that if you ever want to look at a netlist and compare to your RTL, you get to manually trace the connections. There is usually not a good reason to have variables, as they represent nothing in terms of Hardware, and obfuscate the design vs. netlist. I like to see logic types of wire/net/regs, so that it is clear what you are creating in HW. But, as you please, i just tend to cringe when i see them.
Along the same lines, in terms of arrays, I am not a big fan of "bundling signals into arrays"... folks will argue it is "faster" and "easier" to deal with, but to me, it further obfuscates the design. Again, not illegal, but when it comes to OPC (Other people's code) it can be very annoying trying to trace signals, not only within a module, but, arrays across ports too... and then, if they slice those arrays, or decimate them otherwise, it gets even more annoying. Kind of like this rant :)
Ultimately, you can do whatever you want, and especially in an FPGA, some folks tend to be less attention-to-detail about what will be created versus an ASIC. If you are designing an ASIC, I would say you should err on the side of being more pedantic and be able to look at your RTL and know what (to some extent) is going to be created and as such be able to estimate the gate count if you need. To this end, I highly recommend taking the time to draw your design in a drawing program (e.g. visio) to include gates, FFs, decoders, Muxes, FSMs, pseudo-code where appropriate, details of your clock and reset trees, and all CDC crossing logic, etc., including signal names. Once you have that, it is just a matter of translating to RTL... likely, too, as a bonus for those that share my opinion on variables, you will find no variables in your drawing and thus none in your RTL. :)
Using the gezel software, I created a vhdl file from this fdl code:
dp delay_collatz_rev (
in start : ns(1) ; in x0 : ns(16) ;
out done : ns(1) ; out delay : ns(16))
{ reg r : ns(32) ;
reg d : ns(16) ;
reg stop : ns(1) ;
sig x : ns(32) ;
sig d0, dd : ns(16) ;
always { x = start ? x0 : r ;
r = x[0] ? x + (x >> 1) + 1 : x >> 1 ;
done = ( x == 1 ) | ( stop & ~start ) ;
stop = done ;
dd = 1 + x[0] ;
d0 = start ? 0 : d ;
d = done ? d0 : d0 + dd ;
delay = d ;
} }
But when I try to compile this code on the Quartus software, I am getting this error on line 124, which is "sig_10 <= unsigned('1') + unsigned(x(0));"
Error (10647): VHDL type inferencing error at delay_collatz_rev.vhd(124): type of expression is ambiguous - "std_ulogic" or "bit" are two possible matches
library ieee;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
library work;
--use work.std_logic_arithext.all;
-- datapath entity
entity delay_collatz_rev is
port(
start : in std_logic;
x0 : in std_logic_vector(15 downto 0);
done : out std_logic;
delay : out std_logic_vector(15 downto 0);
RST : in std_logic;
CLK : in std_logic
);
end delay_collatz_rev;
architecture RTL of delay_collatz_rev is
-- signal declaration
signal r : std_logic_vector(31 downto 0);
signal r_wire : std_logic_vector(31 downto 0);
signal d : std_logic_vector(15 downto 0);
signal d_wire : std_logic_vector(15 downto 0);
signal stop : std_logic;
signal stop_wire : std_logic;
signal x : std_logic_vector(31 downto 0);
signal d0 : std_logic_vector(15 downto 0);
signal dd : std_logic_vector(15 downto 0);
signal sig_0 : std_logic_vector(31 downto 0);
signal sig_1 : std_logic_vector(31 downto 0);
signal sig_2 : std_logic_vector(31 downto 0);
signal sig_3 : std_logic_vector(31 downto 0);
signal sig_4 : std_logic_vector(31 downto 0);
signal sig_5 : std_logic_vector(31 downto 0);
signal sig_6 : std_logic;
signal sig_7 : std_logic;
signal sig_8 : std_logic;
signal sig_9 : std_logic;
signal sig_10 : std_logic;
signal sig_11 : std_logic_vector(15 downto 0);
signal sig_12 : std_logic_vector(15 downto 0);
signal sig_13 : std_logic_vector(15 downto 0);
signal done_int : std_logic;
signal delay_int : std_logic_vector(15 downto 0);
-- state register & states
begin
-- register updates
dpREG: process (CLK, RST)
begin
if (RST = '1') then
r <= (others => '0');
d <= (others => '0');
stop <= '0';
elsif CLK' event and CLK = '1' then
r <= r_wire;
d <= d_wire;
stop <= stop_wire;
end if;
end process dpREG;
-- combinational logics
dpCMB: process (r, d, stop, x, d0, dd, sig_0, sig_1, sig_2, sig_3
, sig_4, sig_5, sig_6, sig_7, sig_8, sig_9, sig_10, sig_11, sig_12, sig_13
, done_int, delay_int, start, x0)
begin
r_wire <= r;
d_wire <= d;
stop_wire <= stop;
x <= (others => '0');
d0 <= (others => '0');
dd <= (others => '0');
sig_0 <= (others => '0');
sig_1 <= (others => '0');
sig_2 <= (others => '0');
sig_3 <= (others => '0');
sig_4 <= (others => '0');
sig_5 <= (others => '0');
sig_6 <= '0';
sig_7 <= '0';
sig_8 <= '0';
sig_9 <= '0';
sig_10 <= '0';
sig_11 <= (others => '0');
sig_12 <= (others => '0');
sig_13 <= (others => '0');
done_int <= '0';
delay_int <= (others => '0');
done <= '0';
delay <= (others => '0');
if (start = '1') then
sig_0 <= std_logic_vector(resize(unsigned(x0), 32));
else
sig_0 <= r;
end if;
x <= sig_0;
sig_1 <= std_logic_vector(shift_right(unsigned(x), 1));
sig_2 <= std_logic_vector(unsigned(x) + unsigned(sig_1));
sig_3 <= std_logic_vector(unsigned(sig_2) + unsigned(std_logic_vector(to_unsigned(1, 32))));
sig_4 <= std_logic_vector(shift_right(unsigned(x), 1));
if (x(0) = '1') then
sig_5 <= sig_3;
else
sig_5 <= sig_4;
end if;
if (unsigned(x) = 1) then
sig_6 <= '1';
else
sig_6 <= '0';
end if;
sig_7 <= not start;
sig_8 <= stop and sig_7;
sig_9 <= sig_6 or sig_8;
done <= done_int;
sig_10 <= unsigned('1') + unsigned(x(0));
--sig_10 <= std_logic_unsigned(unsigned(unsigned('1')+unsigned(x(0))));
dd <= logic_zero_ext(sig_10, 16);
if (start = '1') then
sig_11 <= std_logic_vector(to_unsigned(0, 16));
else
sig_11 <= d;
end if;
d0 <= sig_11;
sig_12 <= std_logic_vector(unsigned(d0) + unsigned(dd));
if (done_int = '1') then
sig_13 <= d0;
else
sig_13 <= sig_12;
end if;
delay <= delay_int;
done_int <= sig_9;
delay_int <= d;
r_wire <= sig_5;
stop_wire <= done_int;
d_wire <= sig_13;
end process dpCMB;
end RTL;
I am pretty new with Gezel and VHDL, what am I missing?
The Gezel to VHDL generator does not create valid VHDL code, since the used packages does not support addition with target in std_logic as in sig_10 <= unsigned('1') + unsigned(x(0));.
I guess that the problem is due to selection of a single bit in x as x[0], and maybe you can work around this if creating a temporary one bit for x[0], and the assign this with x[0] before making the addition:
sig temp_x_0 : ns(1) ;
...
temp_x_0 = x[0];
dd = 1 + temp_x_0;
But I must admit that I am not that much into Gezel.
After I finished my design compilation on Quartus, I get multiple result for fmax as shown below. I want to know, what does it means? and How can I calculate the fmax of the all design?.
My design is implementation for the following equation:
for(i = 1; i < 5; i++)
{
T += ( ((Rv[i] - Ru[i]))^2 + ((Iv[i] - Iu[i]))^2 )
}
assume the following:
1. use 4 add-sub, 2 squarer, and eight 21-bit register file(parallel input/output) .
2. finished all operation in 8 clock cycles.
Note: - each adder/subtractor is 21-bit and has a selector pin '1' for add or '0' for sub.
- squarer is 9 bit.
- T is 21 bit.
This is the FSM for my design
According the above, this is my code
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity EDCfunction_TopEntity is
port
(
clk, reset : in std_logic;
Rv1 : in std_logic_vector (8-1 downto 0);
Iv1 : in std_logic_vector (8-1 downto 0);
Ru1 : in std_logic_vector (8-1 downto 0);
Iu1 : in std_logic_vector (8-1 downto 0);
Rv2 : in std_logic_vector (8-1 downto 0);
Iv2 : in std_logic_vector (8-1 downto 0);
Ru2 : in std_logic_vector (8-1 downto 0);
Iu2 : in std_logic_vector (8-1 downto 0);
Rv3 : in std_logic_vector (8-1 downto 0);
Iv3 : in std_logic_vector (8-1 downto 0);
Ru3 : in std_logic_vector (8-1 downto 0);
Iu3 : in std_logic_vector (8-1 downto 0);
Rv4 : in std_logic_vector (8-1 downto 0);
Iv4 : in std_logic_vector (8-1 downto 0);
Ru4 : in std_logic_vector (8-1 downto 0);
Iu4 : in std_logic_vector (8-1 downto 0);
T : out std_logic_vector (21-1 downto 0)
);
end EDCfunction_TopEntity;
architecture behavioral of EDCfunction_TopEntity is
type clock_state is (zero, zero_clk2, one, two, two_clk2, three, three_clk2, four, four_clk2, five, six, seven, eight);
type add_sub_type is array (4-1 downto 0) of std_logic_vector (21-1 downto 0);
type squarer_in_type is array (2-1 downto 0) of std_logic_vector (9-1 downto 0);
type squarer_out_type is array (2-1 downto 0) of std_logic_vector (18-1 downto 0);
signal cc_state, cn_state : clock_state;
signal clk_reg_file, reset_reg_file, s_wr_en : std_logic;
signal add_sub_flage, state_mux : std_logic_vector (4-1 downto 0);
signal dataa_add_sub, datab_add_sub, result_add_sub : add_sub_type;
signal dataa_squarer : squarer_in_type;
signal result_squarer : squarer_out_type;
signal w_addr_reg_file, r_addr_reg_file : std_logic_vector (8-1 downto 0);
signal s_w_data_0, s_w_data_1, s_w_data_2, s_w_data_3, s_w_data_4, s_w_data_5, s_w_data_6, s_w_data_7,
s_r_data_0, s_r_data_1, s_r_data_2, s_r_data_3, s_r_data_4, s_r_data_5, s_r_data_6, s_r_data_7
: std_logic_vector (21-1 downto 0);
alias R0 is s_w_data_0(21-1 downto 0);
alias R0H is s_w_data_0(21-1 downto 10);
alias R0L is s_w_data_0(9 downto 0);
alias R1 is s_w_data_1(21-1 downto 0);
alias R1H is s_w_data_1(21-1 downto 10);
alias R1L is s_w_data_1(9 downto 0);
alias R2 is s_w_data_2(21-1 downto 0);
alias R2H is s_w_data_2(21-1 downto 10);
alias R2L is s_w_data_2(9 downto 0);
alias R3 is s_w_data_3(21-1 downto 0);
alias R3H is s_w_data_3(21-1 downto 10);
alias R3L is s_w_data_3(9 downto 0);
alias R4 is s_w_data_4(21-1 downto 0);
alias R4H is s_w_data_4(21-1 downto 10);
alias R4L is s_w_data_4(9 downto 0);
alias R5 is s_w_data_5(21-1 downto 0);
alias R5H is s_w_data_5(21-1 downto 10);
alias R5L is s_w_data_5(9 downto 0);
alias R6 is s_w_data_6(21-1 downto 0);
alias R6H is s_w_data_6(21-1 downto 10);
alias R6L is s_w_data_6(9 downto 0);
alias R7 is s_w_data_7(21-1 downto 0);
alias R7H is s_w_data_7(21-1 downto 10);
alias R7L is s_w_data_7(9 downto 0);
component lpm_adder_subtractor
port
(
add_sub : IN STD_LOGIC ;
dataa : IN STD_LOGIC_VECTOR (20 DOWNTO 0);
datab : IN STD_LOGIC_VECTOR (20 DOWNTO 0);
result : OUT STD_LOGIC_VECTOR (20 DOWNTO 0)
);
end component;
component lpm_squarer
PORT
(
dataa : IN STD_LOGIC_VECTOR (8 DOWNTO 0);
result : OUT STD_LOGIC_VECTOR (17 DOWNTO 0)
);
end component;
component register_file
port
(
clk, reset : in std_logic;
wr_en : in std_logic;
w_addr : in std_logic_vector (8-1 downto 0);
w_data_0 : in std_logic_vector (21-1 downto 0);
w_data_1 : in std_logic_vector (21-1 downto 0);
w_data_2 : in std_logic_vector (21-1 downto 0);
w_data_3 : in std_logic_vector (21-1 downto 0);
w_data_4 : in std_logic_vector (21-1 downto 0);
w_data_5 : in std_logic_vector (21-1 downto 0);
w_data_6 : in std_logic_vector (21-1 downto 0);
w_data_7 : in std_logic_vector (21-1 downto 0);
r_addr : in std_logic_vector (8-1 downto 0);
r_data_0 : out std_logic_vector (21-1 downto 0);
r_data_1 : out std_logic_vector (21-1 downto 0);
r_data_2 : out std_logic_vector (21-1 downto 0);
r_data_3 : out std_logic_vector (21-1 downto 0);
r_data_4 : out std_logic_vector (21-1 downto 0);
r_data_5 : out std_logic_vector (21-1 downto 0);
r_data_6 : out std_logic_vector (21-1 downto 0);
r_data_7 : out std_logic_vector (21-1 downto 0)
);
end component;
begin
A0 : lpm_adder_subtractor port map (add_sub_flage(0), dataa_add_sub(0), datab_add_sub(0), result_add_sub(0));
A1 : lpm_adder_subtractor port map (add_sub_flage(1), dataa_add_sub(1), datab_add_sub(1), result_add_sub(1));
A2 : lpm_adder_subtractor port map (add_sub_flage(2), dataa_add_sub(2), datab_add_sub(2), result_add_sub(2));
A3 : lpm_adder_subtractor port map (add_sub_flage(3), dataa_add_sub(3), datab_add_sub(3), result_add_sub(3));
S0 : lpm_squarer port map (dataa_squarer(0), result_squarer(0));
S1 : lpm_squarer port map (dataa_squarer(1), result_squarer(1));
U0 : register_file port map (clk, reset_reg_file, s_wr_en, w_addr_reg_file, s_w_data_0, s_w_data_1, s_w_data_2,
s_w_data_3, s_w_data_4, s_w_data_5, s_w_data_6, s_w_data_7, r_addr_reg_file,
s_r_data_0, s_r_data_1, s_r_data_2, s_r_data_3, s_r_data_4, s_r_data_5, s_r_data_6,
s_r_data_7);
process (cc_state, reset, Rv1, Iv1, Ru1, Iu1, Rv2, Iv2, Ru2, Iu2, Rv3, Iv3, Ru3, Iu3, Rv4, Iv4, Ru4, Iu4)
begin
case cc_state is
when zero =>
s_wr_en <= '1';
w_addr_reg_file <= "11111111";
R0H <= std_logic_vector(resize(signed(Rv1), R0H'length));
R0L <= std_logic_vector(resize(signed(Ru1), R0L'length));
R1H <= std_logic_vector(resize(signed(Iv1), R1H'length));
R1L <= std_logic_vector(resize(signed(Iu1), R1L'length));
R2H <= std_logic_vector(resize(signed(Rv2), R2H'length));
R2L <= std_logic_vector(resize(signed(Ru2), R2L'length));
R3H <= std_logic_vector(resize(signed(Iv2), R3H'length));
R3L <= std_logic_vector(resize(signed(Iu2), R3L'length));
R4H <= std_logic_vector(resize(signed(Rv3), R4H'length));
R4L <= std_logic_vector(resize(signed(Ru3), R4L'length));
R5H <= std_logic_vector(resize(signed(Iv3), R5H'length));
R5L <= std_logic_vector(resize(signed(Iu3), R5L'length));
R6H <= std_logic_vector(resize(signed(Rv4), R6H'length));
R6L <= std_logic_vector(resize(signed(Ru4), R6L'length));
R7H <= std_logic_vector(resize(signed(Iv4), R7H'length));
R7L <= std_logic_vector(resize(signed(Iu4), R7L'length));
--clk_reg_file <= '1';
--T <= result_add_sub(0);
cn_state <= zero_clk2;
when zero_clk2 =>
r_addr_reg_file <= "11111111";
cn_state <= one;
when one =>
s_wr_en <= '0';
--w_addr_reg_file <= "00001111";
add_sub_flage(0) <= '0';
add_sub_flage(1) <= '0';
add_sub_flage(2) <= '0';
add_sub_flage(3) <= '0';
--r_addr_reg_file <= "00001111";
dataa_add_sub(0) <= std_logic_vector(resize(signed(s_r_data_0 (21-1 downto 10)), dataa_add_sub(0)'length));
datab_add_sub(0) <= std_logic_vector(resize(signed(s_r_data_0 (9 downto 0)), dataa_add_sub(0)'length));
--s_w_data_0 <= result_add_sub(0);
--w_addr_reg_file <= "00000001";
dataa_add_sub(1) <= std_logic_vector(resize(signed(s_r_data_1 (21-1 downto 10)), dataa_add_sub(1)'length));
datab_add_sub(1) <= std_logic_vector(resize(signed(s_r_data_1 (9 downto 0)), dataa_add_sub(1)'length));
--s_w_data_1 <= result_add_sub(1);
--w_addr_reg_file <= "00000010";
dataa_add_sub(2) <= std_logic_vector(resize(signed(s_r_data_2 (21-1 downto 10)), dataa_add_sub(2)'length));
datab_add_sub(2) <= std_logic_vector(resize(signed(s_r_data_2 (9 downto 0)), dataa_add_sub(2)'length));
--s_w_data_2 <= result_add_sub(2);
--w_addr_reg_file <= "00000100";
dataa_add_sub(3) <= std_logic_vector(resize(signed(s_r_data_3 (21-1 downto 10)), dataa_add_sub(3)'length));
datab_add_sub(3) <= std_logic_vector(resize(signed(s_r_data_3 (9 downto 0)), dataa_add_sub(3)'length));
--s_w_data_3 <= result_add_sub(3);
--w_addr_reg_file <= "00001000";
--T <= result_add_sub(3);
--clk_reg_file <= '1';
--r_addr_reg_file <= "11110000";
cn_state <= two;
--state_mux <= "0001";
when two =>
s_wr_en <= '1';
w_addr_reg_file <= "00001111";
R0 <= result_add_sub(0);
R1 <= result_add_sub(1);
R2 <= result_add_sub(2);
R3 <= result_add_sub(3);
dataa_squarer(0) <= result_add_sub(0) (9-1 downto 0);
dataa_squarer(1) <= result_add_sub(1) (9-1 downto 0);
dataa_add_sub(0) <= std_logic_vector(resize(signed(s_r_data_4 (21-1 downto 10)), dataa_add_sub(0)'length));
datab_add_sub(0) <= std_logic_vector(resize(signed(s_r_data_4 (9 downto 0)), dataa_add_sub(0)'length));
dataa_add_sub(1) <= std_logic_vector(resize(signed(s_r_data_5 (21-1 downto 10)), dataa_add_sub(1)'length));
datab_add_sub(1) <= std_logic_vector(resize(signed(s_r_data_5 (9 downto 0)), dataa_add_sub(1)'length));
dataa_add_sub(2) <= std_logic_vector(resize(signed(s_r_data_6 (21-1 downto 10)), dataa_add_sub(2)'length));
datab_add_sub(2) <= std_logic_vector(resize(signed(s_r_data_6 (9 downto 0)), dataa_add_sub(2)'length));
dataa_add_sub(3) <= std_logic_vector(resize(signed(s_r_data_7 (21-1 downto 10)), dataa_add_sub(3)'length));
datab_add_sub(3) <= std_logic_vector(resize(signed(s_r_data_7 (9 downto 0)), dataa_add_sub(3)'length));
cn_state <= two_clk2;
when two_clk2 =>
cn_state <= three;
when three =>
--s_wr_en <= '1';
w_addr_reg_file <= "11110011";
R0 <= std_logic_vector(resize(signed(result_squarer(0)), R0'length));
R1 <= std_logic_vector(resize(signed(result_squarer(1)), R0'length));
R4 <= result_add_sub(0);
R5 <= result_add_sub(1);
R6 <= result_add_sub(2);
R7 <= result_add_sub(3);
add_sub_flage(0) <= '1';
dataa_add_sub(0) <= std_logic_vector(resize(signed(result_squarer(0)), dataa_add_sub(0)'length));
datab_add_sub(0) <= std_logic_vector(resize(signed(result_squarer(1)), datab_add_sub(0)'length));
dataa_squarer(0) <= s_r_data_2 (9-1 downto 0);
dataa_squarer(1) <= s_r_data_3 (9-1 downto 0);
cn_state <= three_clk2;
when three_clk2 =>
cn_state <= four;
when four =>
w_addr_reg_file <= "00000110";
R0 <= result_add_sub(0);
R1 <= std_logic_vector(resize(signed(result_squarer(0)), R0'length));
R2 <= std_logic_vector(resize(signed(result_squarer(1)), R0'length));
add_sub_flage(1) <= '1';
dataa_add_sub(1) <= std_logic_vector(resize(signed(result_squarer(0)), dataa_add_sub(1)'length));
datab_add_sub(1) <= std_logic_vector(resize(signed(result_squarer(1)), datab_add_sub(1)'length));
dataa_squarer(0) <= s_r_data_4 (9-1 downto 0);
dataa_squarer(1) <= s_r_data_5 (9-1 downto 0);
cn_state <= four_clk2;
when four_clk2 =>
cn_state <= five;
when five =>
w_addr_reg_file <= "00001110";
R1 <= result_add_sub(1);
R2 <= std_logic_vector(resize(signed(result_squarer(0)), R2'length));
R3 <= std_logic_vector(resize(signed(result_squarer(1)), R3'length));
add_sub_flage(2) <= '1';
dataa_add_sub(0) <= R0;
datab_add_sub(0) <= result_add_sub(1);
dataa_add_sub(2) <= std_logic_vector(resize(signed(result_squarer(0)), dataa_add_sub(2)'length));
datab_add_sub(2) <= std_logic_vector(resize(signed(result_squarer(1)), datab_add_sub(2)'length));
dataa_squarer(0) <= s_r_data_6 (9-1 downto 0);
dataa_squarer(1) <= s_r_data_7 (9-1 downto 0);
cn_state <= six;
when six =>
w_addr_reg_file <= "00001111";
R0 <= result_add_sub(0);
R1 <= result_add_sub(2);
R2 <= std_logic_vector(resize(signed(result_squarer(0)), R2'length));
R3 <= std_logic_vector(resize(signed(result_squarer(1)), R3'length));
add_sub_flage(3) <= '1';
dataa_add_sub(0) <= result_add_sub(0);
datab_add_sub(0) <= result_add_sub(2);
dataa_add_sub(3) <= std_logic_vector(resize(signed(result_squarer(0)), dataa_add_sub(2)'length));
datab_add_sub(3) <= std_logic_vector(resize(signed(result_squarer(1)), datab_add_sub(2)'length));
cn_state <= seven;
when seven =>
w_addr_reg_file <= "00000011";
R0 <= result_add_sub(0);
R1 <= result_add_sub(3);
dataa_add_sub(0) <= result_add_sub(0);
datab_add_sub(0) <= result_add_sub(3);
--R0 <= result_add_sub(0);
--T <= result_add_sub(0);
cn_state <= eight;
when eight =>
w_addr_reg_file <= "00000001";
R0 <= result_add_sub(0);
T <= result_add_sub(0);
cn_state <= zero;
end case;
--if(state_mux = "0001") then
--end if;
end process;
process (clk, reset)
begin
reset_reg_file <= reset;
if(reset = '1') then
cc_state <= zero;
elsif (clk'event and clk = '1') then
cc_state <= cn_state;
end if;
end process;
end behavioral;
Any help,
Regards
cc_state is presumably being treated as a clock in your 'combinatorial' process, but your code is too complex to make it obvious why. It's likely that you're reading something before assigning to it, which implies clocked functionality. Your synthesis report will tell you what cc_state is clocking, and why.
You need to rewrite your code to simplify it - this is way too complex. Move out your LPM code into a new module which is unclocked. This should be controlled by your 3-bit state signal. Instantiate this in your top-level clocked module, which should contain only the register file, and a simplified FSM.
You should also think about:
Move the stuff in the architecture declarative region into a package
Make use of subtypes to get rid of all the std_logic_vector stuff
If you end up with a case statement in your combinatorial module, make sure that you set default values for all outputs, or assign in all branches (your existing code doesn't assign to s_wr_en in all branches)
If it still doesn't work, post a much simpler question. Your algorithm isn't relevant to the question.
So I have been working on this assignment and it requires me to design a 4-bit ALU being controlled by a couple of bits(namely S1, S0, Cin/C0(carry in) and M) Depending on the value of M the ALU will perform either logical or Arithmetic operations. I have temporarily designed an ALU which works with an input named 'Sel' while I figure out how to take the values of the 3 diff inputs(S0, S1, Cin/C0). I cannot figure out how to concatenate the 3 bits. I have also used '-' for dont care bits while performing logical operations. Also since I haven't used the 3 control selects, Mode (m) feels redundant. So ignore some parts of the code since they aren't useful.
I have attached an image at the end which explains what is expected.
CODE
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_unsigned.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity codeALU is
Port ( A : in STD_LOGIC_VECTOR (3 downto 0);
B : in STD_LOGIC_VECTOR (3 downto 0);
Cin : in STD_LOGIC;
--S0 : in STD_LOGIC;
--S1 : in STD_LOGIC;
Sel : in STD_LOGIC_VECTOR (2 downto 0);
M : in STD_LOGIC;
Cout : out STD_LOGIC;
Z : out STD_LOGIC;
F : out STD_LOGIC_VECTOR (3 downto 0));
end codeALU;
architecture Behavioral of codeALU is
begin
process(A, B, M, Cin, Sel)
--variable X : STD_LOGIC_VECTOR (1 downto 0);
--variable Y : STD_LOGIC_VECTOR (2 downto 0);
variable temp : STD_LOGIC_VECTOR (4 downto 0);
variable Fx : STD_LOGIC_VECTOR (3 downto 0);
variable Cx, Zx : STD_LOGIC;
begin
--X := S1 & S0;
--Y := S1 & S0 & Cin;
Cx := '0';
Zx := '0';
if M = '0' then
Z <= '0';
case Sel is
when "00-" =>
Fx := A AND B;
Zx := '0';
when "01-" =>
Fx := A XOR B;
when "10-" =>
Fx := A OR B;
when "11-" =>
Fx := A XNOR B;
when others =>
null;
end case;
elsif M = '1' then
case Sel is
when "000" =>
temp := (B(3)&B(3 downto 1) + ('0'&A));
Fx := temp(3 downto 0);
Cx := temp(4);
when "001" =>
temp := (A(3)&A(3 downto 1) + ('0'&B));
Fx := temp(3 downto 0);
Cx := temp(4);
when "010" =>
temp := ('0'&A) + ('0'&B);
Fx := temp(3 downto 0);
Cx := temp(4);
when "011" =>
temp := ('0'&A) + ('0'&B) + ('0'&Cin);
Fx := temp(3 downto 0);
Cx := temp(4);
when "100" =>
temp := ('0'&A) + (not B);
Fx := temp(3 downto 0);
Cx := temp(4);
when "101" =>
temp := (not B) + ('0'&A) + 1;
Fx := temp(3 downto 0);
Cx := temp(4);
when "110" =>
temp := ('0'&A) + ('0'&B(3 downto 1));
Fx := temp(3 downto 0);
Cx := temp(4);
when "111" =>
temp := ('0'&B) + ('0'&A(3 downto 1));
Fx := temp(3 downto 0);
Cx := temp(4);
when others =>
null;
end case;
for i in 0 to 3 loop
Zx := Zx or Fx(i);
end loop;
Z <= not Zx;
else null;
end if;
F <= Fx;
Cout <= Cx;
end process;
end Behavioral;
TEST BENCH
![LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--USE ieee.numeric_std.ALL;
ENTITY test2ALU IS
END test2ALU;
ARCHITECTURE behavior OF test2ALU IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT codeALU
PORT(
A : IN std_logic_vector(3 downto 0);
B : IN std_logic_vector(3 downto 0);
Cin : IN std_logic;
Sel : IN std_logic_vector(2 downto 0);
M : IN std_logic;
Cout : OUT std_logic;
Z : OUT std_logic;
F : OUT std_logic_vector(3 downto 0)
);
END COMPONENT;
--Inputs
signal A : std_logic_vector(3 downto 0) := (others => '0');
signal B : std_logic_vector(3 downto 0) := (others => '0');
signal Cin : std_logic := '0';
signal Sel : std_logic_vector(2 downto 0) := (others => '0');
signal M : std_logic := '0';
--Outputs
signal Cout : std_logic;
signal Z : std_logic;
signal F : std_logic_vector(3 downto 0);
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: codeALU PORT MAP (
A => A,
B => B,
Cin => Cin,
Sel => Sel,
M => M,
Cout => Cout,
Z => Z,
F => F
);
-- Stimulus process
stim_proc: process
begin
-- hold reset state for 100 ns.
wait for 100 ns;
A <= "1001";
B <= "1111";
M <= '0';
wait for 50 ns;
Sel <= "00-";
wait for 50 ns;
Sel <= "01-";
wait for 50 ns;
Sel <= "10-";
wait for 50 ns;
Sel <= "11-";
wait for 50 ns;
M <= '1';
Sel <= "000";
wait for 50 ns;
Sel <= "001";
wait for 50 ns;
Sel <= "010";
wait for 50 ns;
Sel <= "011";
wait for 50 ns;
Sel <= "100";
wait for 50 ns;
Sel <= "101";
wait for 50 ns;
Sel <= "110";
wait for 50 ns;
Sel <= "111";
-- insert stimulus here
wait;
end process;
END;][1]
What you tried to do with X and Y (and which you commented out) is a perfectly reasonable way of concatenating your selects. The problem is the don't-cares. The ordinary case statement does not handle don't-cares the way you're expecting (i.e. it doesn't match against them as if they can be anything - it handles them as a unique std_logic value same as everything else). If you have tools that support VHDL-2008, you can use case?, which does match against don't-care values the way you want. You could even concatenate M into your select as well and shorten your code a bit. Like:
process (all)
variable sel : std_logic_vector(3 downto 0);
begin
sel := M & S1 & S0 & Cin;
case? sel is
when "000-" =>
Fx := A and B;
when "001-" =>
Fx := A or B;
...
when "1000" =>
...
(Note that I'm using sel here as an internal variable instead of a port.)
If you can't use VHDL-2008, you will have to nest your if/case statements appropriately. Hint: you can use a slice of sel in a case statement, so if Cin is always a don't-care for M = '0', you can do something like:
process (M, S0, S1, Cin, A, B)
variable sel : std_logic_vector(2 downto 0);
begin
sel := S1 & S0 & Cin;
if M = '0' then
case sel(2 downto 1) is -- Cin is don't-care
when "00" =>
Fx := A and B;
when "01" =>
Fx := A or B;
...
else
case sel is -- all control bits are significant
when "000" =>
...
As Paebbels pointed out, a better solution for you perhaps would be just to explicitly give multiple choices where there's a don't-care, though that may get tedious for designs with more control bits.