place_design Error for clock constraint VHDL Vivado FPGA - syntax-error

So I'm trying to design a 'vending machine' sequential circuit in Vivado for the ZYBO FPGA board. However, every time I try to get past the Implementation stage I get a bunch of errors, the main one being
[Place 30-58] IO placement is infeasible. Number of unplaced terminals (1) is greater than
number of available sites (0).
The following Groups of I/O terminals have not sufficient capacity:
IO Group: 0 with : SioStd: LVCMOS18 VCCO = 1.8 Termination: 0 TermDir: In RangeId: 1
has only 0 sites available on device, but needs 1 sites.
Term: clk
I did try the Auto I/O planning, but all that ended up doing was removing the pin constraints. It got through implementation at that point but then of course couldn't generate the bit stream because none of the ports were mapped to pins.
Here's my VHDL design
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY des_src IS
PORT (
reset : IN std_logic;
clk : IN std_logic;
QDN : IN std_logic_vector(2 DOWNTO 0);
PC : OUT std_logic_vector(1 DOWNTO 0)
);
END des_src;
ARCHITECTURE behavioral OF des_src IS
TYPE statetype IS (Start, Five, Ten, Fifteen, Twenty, Twentyfive, Thirty, Thirtyfive, Fourty, Fourtyfive);
SIGNAL currentstate, nextstate : statetype;
BEGIN
fsm1: PROCESS (QDN, currentstate)
BEGIN
CASE currentstate IS
WHEN Start =>
PC <= "00";
CASE QDN IS
WHEN "000" =>
nextstate <= Start;
WHEN "001" =>
nextstate <= Five;
WHEN "010" =>
nextstate <= Ten;
WHEN "100" =>
nextstate <= Twentyfive;
WHEN OTHERS =>
nextstate <= Start;
END CASE;
WHEN Five =>
PC <= "00";
CASE QDN IS
WHEN "000" =>
nextstate <= Five;
WHEN "001" =>
nextstate <= Ten;
WHEN "010" =>
nextstate <= Fifteen;
WHEN "100" =>
nextstate <= Thirty;
WHEN OTHERS =>
nextstate <= Start;
END CASE;
WHEN Ten =>
PC <= "00";
CASE QDN IS
WHEN "000" =>
nextstate <= Ten;
WHEN "001" =>
nextstate <= Fifteen;
WHEN "010" =>
nextstate <= Twenty;
WHEN "100" =>
nextstate <= Thirtyfive;
WHEN OTHERS =>
nextstate <= Start;
END CASE;
WHEN Fifteen =>
PC <= "00";
CASE QDN IS
WHEN "000" =>
nextstate <=Fifteen;
WHEN "001" =>
nextstate <= Twenty;
WHEN "010" =>
nextstate <= Twentyfive;
WHEN "100" =>
nextstate <= Fourty;
WHEN OTHERS =>
nextstate <= Start;
END CASE;
WHEN Twenty =>
PC <= "00";
CASE QDN IS
WHEN "000" =>
nextstate <= Twenty;
WHEN "001" =>
nextstate <= Twentyfive;
WHEN "010" =>
nextstate <= Thirty;
WHEN "100" =>
nextstate <= Fourtyfive;
WHEN OTHERS =>
nextstate <= Start;
END CASE;
WHEN Twentyfive =>
PC <= "10";
nextstate <= Start;
WHEN Thirty =>
PC <= "01";
nextstate <= Twentyfive;
WHEN Thirtyfive =>
PC <= "01";
nextstate <= Thirty;
WHEN Fourty =>
PC <= "01";
nextstate <= Thirtyfive;
WHEN Fourtyfive =>
PC <= "01";
nextstate <= Fourty;
END CASE;
END PROCESS;
fsm2: PROCESS (reset, clk)
BEGIN
IF (reset = '0') THEN
currentstate <= Start;
ELSIF (clk'EVENT) AND (clk = '1') THEN
currentstate <= nextstate;
END IF;
END PROCESS;
END behavioral;
Here are my constraints
##Buttons
##IO_L20N_T3_34
set_property IOSTANDARD LVCMOS33 [get_ports {QDN[0]}]
set_property PACKAGE_PIN R18 [get_ports {QDN[0]}]
##IO_L24N_T3_34
set_property IOSTANDARD LVCMOS33 [get_ports {QDN[1]}]
set_property PACKAGE_PIN P16 [get_ports {QDN[1]}]
##IO_L18P_T2_34
set_property IOSTANDARD LVCMOS33 [get_ports {QDN[2]}]
set_property PACKAGE_PIN V16 [get_ports {QDN[2]}]
##IO_L7P_T1_34
set_property IOSTANDARD LVCMOS33 [get_ports reset]
set_property PACKAGE_PIN Y16 [get_ports reset]
##LEDs
##IO_L23P_T3_35
set_property IOSTANDARD LVCMOS33 [get_ports {PC[0]}]
set_property PACKAGE_PIN M14 [get_ports {PC[0]}]
##IO_L23N_T3_35
set_property IOSTANDARD LVCMOS33 [get_ports {PC[1]}]
set_property PACKAGE_PIN M15 [get_ports {PC[1]}]
create_clock -period 10.000 -name clk -waveform {0.000 5.000} [get_ports clk]
set_input_delay -clock [get_clocks clk] -min -add_delay 0.000 [get_ports {QDN[*]}]
set_input_delay -clock [get_clocks clk] -max -add_delay 0.000 [get_ports {QDN[*]}]
set_input_delay -clock [get_clocks clk] -min -add_delay 0.000 [get_ports reset]
set_input_delay -clock [get_clocks clk] -max -add_delay 0.000 [get_ports reset]
set_output_delay -clock [get_clocks clk] -min -add_delay 0.000 [get_ports {PC[*]}]
set_output_delay -clock [get_clocks clk] -max -add_delay 0.000 [get_ports {PC[*]}]
I'm using Vivado 2015.2 and designing for the ZYBO development board.
Any and all help is appreciated.
Edit 8/26/15
Alright, I got my code working for the most part. I was able to use
set_property PACKAGE_PIN L16 [get_ports clk]
set_property IOSTANDARD LVCMOS33 [get_ports clk]
create_clock -period 10.000 -name clk -waveform {0.000 5.000} [get_ports clk]
for my clock. However, this clock is way faster than I want it to be (125MHz), so I know I have to use clock division and in the constraint file generate a clock, but do I need to assign the generated clock to a pin? And does anyone have any tips on how to include the clock divider in my current vhdl code? Do I just make it another process, and add another port, or is it more complicated than that?

You did not assign a pin to the clk primary. I guess Vivado decides that a 1.8V LVCMOS input is needed for it (probably the default) but there are no LVCMOS 1V8 user pins available on the Zybo: the only 1V8 bank is 501 and it is already fully used by Ethernet, USB OTG, SD card, UART and press-buttons. As you probably told Vivado that you are using the Zybo, it cannot solve this issue alone.
So, if you have an external clock source, wire it to one of the pmod connectors, declare the corresponding pin as LVCMOS3V3 and assign it to clk. Else, if you want your clock to be driven by the processing system, you must explicitly wire one of the 4 FCLK PS-to-PL clocks to the clk input of your design.
The easiest way to do this, in my opinion, is to turn your design into an IP (see Vivado documentation), instantiate it in a block design, add a processing system and the primary I/Os you need and do the wiring.

Related

Q : Serializer/Deserializer problems

I want to implement a Serializer/Deserializer (SerDes) in VHDL. Actually, it is more like a simple Shift register. The shift register store a value and shifts to convert information from parallel to serial.The output of the register is 16 bits. It has an 16-bit Parallel input, which allows us to load the register with a new value. The load input allows to load a new value when a falling edge of the clock arrives.
Moreover, I also made a testBench with two SerDes component connected together to implement a sort of loop/ring. Unfortunately, I don't know why when I send a data with the value "1234" from the parallel input I receive "3412" in my parallel output : waveform testBench.
Below my code :
SerDes.vhd :
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity SerDes is
generic (
Dbits : integer := 16
);
Port (
serial_clk : in STD_LOGIC;
clk : in STD_LOGIC;
rstn : in STD_LOGIC;
load : in STD_LOGIC;
enable : in STD_LOGIC;
serial_in : in STD_LOGIC;
parallel_in : in STD_LOGIC_VECTOR(Dbits-1 downto 0);
dout : out STD_LOGIC;
parallel_out : out STD_LOGIC_VECTOR(Dbits-1 downto 0)
);
end SerDes;
architecture Behavioral of SerDes is
signal rx_counter : integer := 0 ;
signal shift_reg : STD_LOGIC_VECTOR(Dbits-1 downto 0);
type TYPE_STATE is (Idle,ShiftIn);
signal CURRENT_STATE : TYPE_STATE := Idle;
signal serial_clock_D : STD_LOGIC := '0';
begin
serialization : process(serial_clk,rstn) --Envoyer une donnée parallèle et la récupérer sur la sortie série
begin
if (rstn = '0') then
shift_reg <= (others => '0');
rx_counter <= 0;
serial_clock_D <= '0';
CURRENT_STATE <= Idle;
elsif (clk = '1' and clk'event) then
case CURRENT_STATE is
when Idle =>
if (enable = '1') then
CURRENT_STATE <= ShiftIn;
else
CURRENT_STATE <= Idle;
end if;
if (load = '1') then
shift_reg <= parallel_in;
end if;
parallel_out <= shift_reg;
rx_counter <= 0;
when ShiftIn =>
if(serial_clk = '1' and serial_clock_D = '0') then
shift_reg <= shift_reg(14 downto 0) & serial_in;
end if;
if (rx_counter = Dbits-1) then
CURRENT_STATE <= Idle;
else
rx_counter <= rx_counter + 1;
end if;
end case;
end if;
end process;
dout <= shift_reg(15);
end Behavioral;
SERDESTestbench.vhd :
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity SERDES_Testbench is
-- Port ( );
end SERDES_Testbench;
architecture Behavioral of SERDES_Testbench is
constant Dbits : integer := 16;
component SerDes is
generic (
Dbits : integer := 16
);
Port (
serial_clk : in STD_LOGIC;
clk : in STD_LOGIC;
rstn : in STD_LOGIC;
load : in STD_LOGIC;
enable : in STD_LOGIC;
serial_in : in STD_LOGIC;
parallel_in : in STD_LOGIC_VECTOR(Dbits-1 downto 0);
dout : out STD_LOGIC;
parallel_out : out STD_LOGIC_VECTOR(Dbits-1 downto 0)
);
end component;
signal serial_clk : STD_LOGIC := '0';
signal clk : STD_LOGIC := '0';
signal rstn : STD_LOGIC;
signal load : STD_LOGIC := '1';
signal enable : STD_LOGIC := '0';
signal serial_in : STD_LOGIC;
signal parallel_in : STD_LOGIC_VECTOR(Dbits-1 downto 0) := (others => '0');
signal dout : STD_LOGIC;
signal parallel_out : STD_LOGIC_VECTOR(Dbits-1 downto 0);
signal dout2 : STD_LOGIC;
signal parallel_out2 : STD_LOGIC_VECTOR(Dbits-1 downto 0);
signal end_of_simu : STD_LOGIC := '0';
begin
SR1 : SerDes
generic map(
Dbits => Dbits
)
Port map(
serial_clk => serial_clk,
clk => clk,
rstn => rstn,
load => load,
enable => enable,
serial_in => dout2,
parallel_in => parallel_in,
dout => dout,
parallel_out => parallel_out
);
SR2 : SerDes
generic map(
Dbits => Dbits
)
Port map(
serial_clk => serial_clk,
clk => clk,
rstn => rstn,
load => load,
enable => enable,
serial_in => dout,
parallel_in => parallel_in,
dout => dout2,
parallel_out => parallel_out2
);
stimulus : process
begin
rstn <= '0';
wait for 100 ns;
rstn <= '1';
wait for 100 ns;
parallel_in <= X"1234";
enable <= '1';
wait;
end process;
clocking : process
begin
IF end_of_simu /= '1' THEN
clk <= not clk;
wait for 5 ns;
ELSE
assert false report "end of test" severity note;
WAIT;
END IF;
end process;
sclk_gen : process
begin
IF end_of_simu /= '1' THEN
serial_clk <= not serial_clk;
wait for 100 ns;
ELSE
assert false report "end of test" severity note;
WAIT;
END IF;
end process;
end Behavioral;

Syntax error in verilog

I have about six errors but they are all the same.
The error goes as such: near "?": syntax error, unexpected '?'
I've been trying to figure out how to fix this and I've looked at other problems in stackoverflow relating to this problem but to no avail. At first I thought it was how I was formatting my ternary statements but that wasn't it. So what could the prroblem be?
Code:
always_ff#(posedge clk, posedge reset)
if (reset) state <= S0;
else state <= nextstate;
always_comb
case (state)
S0: OpCode1 ? nextstate <= S2 : nextstate <= S1;
S1: OpCode2 ? nextstate <= S8 : nextstate <= S4;
S2: OpCode2 ? nextstate <= S3 : nextState <= S9;
S3: nextstate <= S0;
S4: A ? nextstate <= S5 : nextstate <= S13;
S5: B ? nextstate <= S7 : nextstate <= S6;
S6: Binv ? nextstate <= S14 : nextstate <= S13;
S7: Binv ? nextstate <= S13 : nextstate <= S14;
endcase
Note S1 to S14 are part of an enum that holds 5 bits[4:0]. The rest are inputs.
I don't see the result of ternary operation being assigned to a register.
Try rewriting it as below:
nextstate = (OpCode1) ? S2 : S1;

vhdl 4 bit vedic multiplier

entity fourbitmult is
Port ( a,b : in STD_LOGIC_VECTOR (3 downto 0);
p : out STD_LOGIC_VECTOR (7 downto 0));
end fourbitmult;
architecture Behavioral of fourbitmult is
component twobitmult
port(a,b:in std_logic_vector(1 downto 0);
p:out std_logic_vector (3 downto 0));
end component;
component rca
port(a,b:in std_logic_vector(3 downto 0);
s:out std_logic_vector(3 downto 0);
carry:out std_logic;
cin:in std_logic='0'
);
end component;
component halfadder
port(a,b:in std_logic;
s,c:out std_logic);
end component;
signal c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,c16,c17,c18,c19,c20,c21,c22: std_logic;
begin
m1:twobitmult port map(a(0),a(1),b(0),b(1),p(0),p(1),c1,c2);
m2:twobitmult port map(a(2),a(3),b(0),b(1),c15,c16,c17,c18);
m3:twobitmult port map(a(0),a(1),b(2),b(3),c19,c20,c21,c22);
m4:twobitmult port map(a(2),a(3),b(2),b(3),c7,c8,c9,c10);
r1:rca port map(c15,c16,c17,c18,c19,c20,c21,c22,c3,c4,c5,c6,c12);
r2:rca port map(c1,c2,c7,c8,c3,c4,c5,c6,p(2),p(3),p(4),p(5),c11);
c13<=c11 or c12;
h1:halfadder port map(c13,c9,p(6),c14);
h2:halfadder port map(c14,c10,p(7));
end Behavioral;
I wrote a VHDL code for the 4 bit vedic multiplier.
I am getting an error as:
Line 45. parse error, unexpected EQ, expecting SEMICOLON or CLOSEPAR"..
The syntax is perfectly right, I don't understand why it's an error. What could be wrong?
The syntax is perfectly right
Not quite.
cin:in std_logic='0'
Should be
cin: in std_logic := '0'
------------------^
You're also missing the context clause at the beginning:
library ieee;
use ieee.std_logic_1164.all;
You've deleted that and some header comments apparently, without indicating which line was line 45 (and it's the line excerpted above). Your example isn't quite a Minimal, Complete, and Verifiable example.
Syntax errors tend to show up easily when you use white space and indentation consistently and well.
Willing to make a claim about the semantics?
Addendum for " More actuals found than formals in port map"
As you've discovered you also have semantic errors as well as the above syntax error. While you didn't update your question, those errors can be explained here too.
The " More actuals found than formals in port map" for original lines 54 - 59 are because you don't have the same number of ports in the port map associations as are declared in the component declarations for twobitmult and rca instances.
You can cure these by using named association which allows you to use a formal's array port elements associated with an array base element type actual. (Allowing more association list entries than the number of ports).
Note that you appear to have an error with the rca component declaration, there are more port map associations shown than are possible by expanding array types.
It appears carry is intended to be an array type (and the following has been annotated to reflect that).
Also note that your array types in your components are declared with port element indexes in a descending order and you associate them with ascending order elements of entity fourbitmult array type ports.
Should you be able to use slices of the actuals with the same range direction as they are declared the association list entry could be simplified as a => a(1 downto 0), for example. The same holds true for other places you can connect slice actuals.
So making the number of ports match by using formal elements:
library ieee;
use ieee.std_logic_1164.all;
entity fourbitmult is
port (
a,b: in std_logic_vector (3 downto 0);
p: out std_logic_vector (7 downto 0));
end fourbitmult;
architecture behavioral of fourbitmult is
component twobitmult
port (
a,b: in std_logic_vector (1 downto 0);
p: out std_logic_vector (3 downto 0)
);
end component;
component rca
port (
a,b: in std_logic_vector (3 downto 0);
s: out std_logic_vector (3 downto 0);
carry: out std_logic_vector (3 downto 0); -- std_logic;
cin: in std_logic := '0' -- formerly line 45
);
end component;
component halfadder
port (
a,b: in std_logic;
s,c: out std_logic
);
end component;
signal c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,
c13,c14,c15,c16,c17,c18,c19,c20,c21,c22: std_logic;
begin
m1:
twobitmult
port map (
-- a(0),a(1),b(0),b(1),p(0),p(1),c1,c2
a(1) => a(0),
a(0) => a(1),
b(1) => b(0),
b(0) => b(1),
p(3) => p(0),
p(2) => p(1),
p(1) => c1,
p(0) => c2
);
m2:
twobitmult
port map (
-- a(2),a(3),b(0),b(1),c15,c16,c17,c18
a(1) => a(2),
a(0) => a(3),
b(1) => b(0),
b(0) => b(1),
p(3) => c15,
p(2) => c16,
p(1) => c17,
p(0) => c18
);
m3:
twobitmult
port map (
-- a(0),a(1),b(2),b(3),c19,c20,c21,c22
a(1) => a(0),
a(0) => a(1),
b(1) => b(2),
b(0) => b(3),
p(3) => c19,
p(2) => c20,
p(1) => c21,
p(0) => c22
);
m4:
twobitmult
port map (
-- a(2),a(3),b(2),b(3),c7,c8,c9,c10
a(1) => a(2),
a(0) => a(3),
b(1) => b(2),
b(0) => b(3),
p(3) => c7,
p(2) => c8,
p(1) => c9,
p(0) => c10
);
r1:
rca
port map (
--c15,c16,c17,c18,c19,c20,c21,c22,c3,c4,c5,c6,c12
a(3) => c15,
a(2) => c16,
a(1) => c17,
a(0) => c18,
b(3) => c19,
b(2) => c20,
b(1) => c21,
b(0) => c22,
carry(3) => c3,
carry(2) => c4,
carry(1) => c5,
carry(0) => c6,
cin => c12
);
r2:
rca
port map (
-- c1,c2,c7,c8,c3,c4,c5,c6,p(2),p(3),p(4),p(5),c11
a(3) => c1,
a(2) => c2,
a(1) => c7,
a(0) => c8,
b(3) => c3,
b(2) => c4,
b(1) => c5,
b(0) => c6,
carry(3) => p(2),
carry(2) => p(3),
carry(1) => p(4),
carry(0) => p(5),
cin => c11
);
c13 <= c11 or c12;
h1:
halfadder
port map (
c13,c9,p(6),c14
);
h2:
halfadder
port map (
c14,c10,p(7)
);
end behavioral;
This analyzes, but without the entity/architecture pairs for the declared components can't be elaborated, nor the functionality verified.

Altera DE0-nano. Struggling to make a SPI slave device

I'm new to VHDL and I thought I could try to make a slave SPI device as training, but it's not working quite as expected. Below my current code. It's compiles and upload just fine, but it's not working as intended. Right now I have the leds connected to the signal "bitnumber", bitnumber is supposed to increment on each rising edge of CLK and then reset to zero when the SS pin is pulled LOW (indicating that the transfer is complete), but it doesn't do that. I've connected my Altera DE0-nano to my arduino which is simply pulling the SS LOW, sends four clock pulses and then pulls the SS back high, I've put a 1s delay between each transition. The leds on my altera board does change it's pattern every second, but it does so on both rising and falling edge of the clock, also the led pattern seems completely random, even showing some leds in a dimmed state. The leds become black when the SS pin goes back HIGH though, that's good.
enter code here
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity SPI2 is
PORT (LED : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
GPIO_0 : IN STD_LOGIC_VECTOR(7 DOWNTO 0));
end SPI2;
architecture SPI2_beh of SPI2 is
signal SPIdataregister : STD_LOGIC_VECTOR(7 DOWNTO 0);
signal bitnumber : STD_LOGIC_VECTOR(7 DOWNTO 0);
begin
LED <= bitnumber;
process(GPIO_0(5), GPIO_0(3))
begin
if ((GPIO_0(5)) = '1') then
bitnumber <= (bitnumber + '1');
end if;
if ((GPIO_0(3)) = '1') then
bitnumber <= "00000000";
end if;
end process;
process(bitnumber)
begin
case bitnumber is
when "00000001" => SPIdataregister(0) <= GPIO_0(7);
when "00000010" => SPIdataregister(1) <= GPIO_0(7);
when "00000011" => SPIdataregister(2) <= GPIO_0(7);
when "00000100" => SPIdataregister(3) <= GPIO_0(7);
when "00000101" => SPIdataregister(4) <= GPIO_0(7);
when "00000110" => SPIdataregister(5) <= GPIO_0(7);
when "00000111" => SPIdataregister(6) <= GPIO_0(7);
when "00001000" => SPIdataregister(7) <= GPIO_0(7);
when others => SPIdataregister <= SPIdataregister;
end case;
end process;
end SPI2_beh;
enter code here
I would start by changing the main process to:
process(GPIO_0(5), GPIO_0(3))
variable change_flag : STD_LOGIC := 1;
begin
if GPIO_0(3) = '1' then
bitnumber <= "00000000";
else
if GPIO_0(5) = '0' --btw here, GPIO_0(3) = '0' also
change_flag := '1';
else --btw here, GPIO_0(3) = '0' and GPIO_0(5) = '1'
if change_flag = '1' then
bitnumber <= bitnumber + 1;
change_flag := '0';
end if;
end if;
end if;
end process;
The variable change_flag introduces memory, to ensure the process only reacts once to specifically a rising edge of GPIO_0(5). Without memory implemented like this, you could get the desired effect by having two processes: one dependent on GPIO_0(5) and one dependent on GPIO_0(3). The risk then is of both changing at the same time and causing a conflict: two signals trying to control/change the same output. The above way is better and should be reliable for your purposes.
Secondly, increment bitnumber using
bitnumber <= bitnumber + 1;
note, use the 1 without the quotes. The quotes indicate binary '1' and '0' from what I understand.
Good luck!!

Design of "simple" VHDL module still drives me mad

Thanks to all your input, I implemented your suggestions, however the problem remains the same. The result in simulation works fine, but the hardware
outputs something different. Just to briefly recap, I have two ctrl signals that determine the behaviour of the entity:
GET (ctrl = "00000000") sets register tx to input of op1
SH1_L (ctrl = "00000001") res := (op1 << 1) | tx;
tx := tx >> 31;
Here is the VHDL code:
library ieee;
use ieee.std_logic_1164.all;
entity test is
port
(
op1 : in std_logic_vector(31 downto 0); -- Input operand
ctrl : in std_logic_vector(7 downto 0); -- Control signal
clk : in std_logic; -- clock
res : out std_logic_vector(31 downto 0) -- Result
);
end;
architecture rtl of test is
type res_sel_type is (GET, SH1_L);
constant Z : std_logic_vector(31 downto 0) := (others => '0');
signal res_sel : res_sel_type;
signal load : std_logic := '0';
signal shl : std_logic := '0';
signal tx : std_logic_vector(31 downto 0) := (others => '0');
signal inp1 : std_logic_vector(31 downto 0) := (others => '0');
begin
dec_op: process (ctrl, op1)
begin
res_sel <= GET;
load <= '0';
shl <= '0';
inp1 <= ( others => '0');
case ctrl is
-- store operand
when "00000000" =>
inp1 <= op1;
load <= '1';
res_sel <= GET;
-- 1-bit left-shift with carry
when "00000001" =>
inp1 <= op1;
shl <= '1';
res_sel <= SH1_L;
when others =>
-- Leave default values
end case;
end process;
sel_out: process (res_sel, inp1, tx)
begin
case res_sel is
when SH1_L =>
res <= ( inp1(30 downto 0) & '0' ) or tx;
when others =>
res <= (others => '0');
end case;
end process;
sync: process(clk)
begin
if clk'event and clk = '1' then
if load = '1' then
tx <= op1;
elsif shl = '1' then
tx <= Z(30 downto 0) & op1(31);
end if;
end if;
end process;
end rtl;
TESTPROGRAM
GET 0 (this sets tx <= 0 )
SH1_L 0xfedcba90 exp. output: 0xfdb97520 act. output = 0xfdb97521
SH1_L 0x7654321f exp. output: 0xeca8643f act. output = 0xeca8643f
SH1_L 0x71234567 exp. output: 0xe2468ace act. output = 0xe2468ace
As you can see, the last bit is wrong for the first SH1_L operation. The first SH1_L operation produces a carry for the NEXT SH1_L operation since
the MSB is set to one of the input, however, it seems that this carry is already considered in the current SH1_L operation, which is wrong (tx should be zero).
I checked the synthesis report and there are no latches, so I am a bit clueless and almost desperate what is going wrong here. I use Xilinx ISE 12.1 for
synthesis, could there be a problem because I do not have a reset signal in my architecture, that the wrong kind of latches are instantiated?
Many thanks for further helpful comments to solve this issue,
Patrick
Unlike RTL simulation, real-life timing of inputs and clocks is not ideal. For example, the clock tree might have a longer delay than input buffers or vice versa. Did you take this into account?