'Opt_Design Error' in Vivado when trying Run Implementation - vhdl

Trying to make a UART Transmitter to send a data from FPGA to PC; 9600 baudrate, 8-bits, no parity, 1 start & stop bit; I wrote a code with VHDL, run synthesis and simulate it in a way I like it to be. I wanted to see it with BASYS 3 FPGA, After created constraints, Run Implementation issued an error in which its called "Opt_Design Error".
library ieee;
use ieee.std_logic_1164.all;
entity rs232_omo is
generic(clk_max:integer:=10400); --for baudrate
port(
clk : in std_logic;
rst : in std_logic;
start : in std_logic;
input : in std_logic_vector(7 downto 0);
done : out std_logic;
output : out std_logic;
showstates: out std_logic_vector(3 downto 0)
);
end entity;
architecture dataflow of rs232_omo is
type states is (idle_state,start_state,send_state,stop_state);
signal present_state,next_state : states;
signal data,data_next : std_logic;
begin
process(clk,rst)
variable count : integer range 0 to clk_max;
variable index : integer range 0 to 10;
begin
if rst='1' then
present_state<=idle_state;
count:=0;
data<='1';
done<='0';
elsif rising_edge(clk) then
present_state<=next_state;
count:=count+1;
index:=index+1;
data<=data_next;
end if;
end process;
process(present_state,data,clk,rst,start)
variable count : integer range 0 to clk_max;
variable index : integer range 0 to 10;
begin
done<='0';
data_next<='1';
case present_state is
when idle_state =>
showstates<="1000";
data_next<='1';
if start='1' and rst='0' then
count:=count+1;
if count=clk_max then
next_state<=start_state;
count:=0;
end if;
end if;
when start_state =>
showstates<="0100";
data_next<='0';
count:=count+1;
if count=clk_max then
next_state<=send_state;
count:=0;
end if;
when send_state =>
showstates<="0010";
count:=count+1;
data_next<=input(index);
if count=clk_max then
if index=7 then
index:=0;
next_state<=stop_state;
else
index:=index+1;
end if;
count:=0;
end if;
when stop_state =>
showstates<="0001";
count:=count+1;
if count=clk_max then
next_state<=idle_state;
done<='1';
count:=0;
end if;
end case;
end process;
output<=data;
end architecture;
This's the error message in detail
"[DRC MDRV-1]Multiple Driver Nets:Net done_OBUF has multiple drivers:
done_OBUF_inst_i_1/O,and done_reg/Q"
"[Vivado_Tcl 4-78] Error(s) found during DRC. Opt_Design not run."
What would be the reason for this error?

You are assigning done both in the first and the second process, which is exactly what the implementation is complaining about, you cannot have multiple drivers.
Remove done<='0'; from the first process and it should complete the implementation.
(I didn't check if the rest of the code is doing exactly what you want.)

Related

How to use the internal oscillator in an FPGA (Lattice MachXO3)?

I'm trying to make a Blink-LED program for a Lattice MachXO3L breakout board. I believe I have the internal-oscillator set up, I just don't know how to connect to its output and make use of it, I get errors when I try. This is on a breakout board which has an LED and a switch. It should oscillate at 1Hz when the switch is flipped one way, and be off when the switch is flipped the other way.
I'e read the PLL usage guide and searched for answers on the internet. I believe I'm close, and just hung up on some syntax issue due to being new to VHDL & FPGAs. Basically, my main code is the 'process and all code below it. Anything above that is basically stuff from the PLL usage guide.
library ieee;
use ieee.std_logic_1164.all;
library machxo3l;
use machxo3l.all;
entity led_blink is
port (
i_switch_1 : in std_logic;
o_led_1 : out std_logic;
i_clock : in std_logic;
osc_int : out std_logic
);
end led_blink;
architecture rtl of led_blink is
COMPONENT OSCH
-- synthesis translate_off
GENERIC (NOM_FREQ: string := "12.09");
-- synthesis translate on
PORT ( STDBY:IN std_logic;
OSC:OUT std_logic);
END COMPONENT;
attribute NOM_FREQ : string;
attribute NOM_FREQ of OSCHinst0 : label is "12.09";
constant C_CNT_1HZ : natural := 6000000;
signal R_CNT_1HZ : natural range 0 to C_CNT_1HZ;
signal R_1HZ : std_logic := '0';
begin
OSCHInst0: OSCH
-- synthesis translate_off
GENERIC MAP(NOM_FREQ => "12.09")
-- synthesis translate on
PORT MAP (STDBY => '0',
OSC => osc_int
);
p_1HZ : process (i_clock) is
begin
if rising_edge(i_clock) then
if R_CNT_1HZ = C_CNT_100HZ-1 then
R_1HZ <= not R_1Hz;
R_CNT_1HZ <= 0;
else
R_CNT_1HZ <= R_CNT_1HZ + 1;
end if;
end if;
end process;
osc_int <= i_clock;
o_led_1 <= R_1HZ when (i_switch_1 = '0') else not R_1HZ;
end rtl;
If I try and assign osc_int to the sensitivity list of the p_1Hz process, I get an error stating that I can not read from an output.
Just a side-note in case other viewers get confused like me, driving i_clock from osc_int appears illogical, because it uses an assignment that seems to suggest the reverse occurs osc_int <= i_clock. Correct me if I'm wrong, but it's assigning an input, to an output, which appears confusing to non-hdl programmers because the direction is decided by the input/output types, rather than the assignment operator itself.
When I do this (link i_clk to osc_int), it saves without giving me errors, it isn't until I try to synthesize the code that it says there are multiple non-tristate drivers for i_clock. The only way I can imagine this being true is if the 'port' from the 'component' section named OSC, being mapped to osc_int, creates two driving signals both linked to i_clock in that single osc_int <= i_clock; statement. But if that's true, how would you access the clock's output at all?
If I just remove the osc_int <= i_clock statement, it works, just with the LED constantly-on/constantly-off, not oscillating/constantly-off.
The clock generated came from inside the OSCH component. Then you don't need any i_clock to achieve what you want. The output of the internal oscillator is the OUT port of the OSCH component.
you can try this :
entity led_blink is
port (
i_switch_1 : in std_logic; -- from the input switch : OK
o_led_1 : out std_logic -- to the blinking led : OK
);
end led_blink;
architecture rtl of led_blink is
COMPONENT OSCH
-- synthesis translate_off
GENERIC (NOM_FREQ: string := "12.09");
-- synthesis translate on
PORT ( STDBY:IN std_logic;
OSC:OUT std_logic);
END COMPONENT;
attribute NOM_FREQ : string;
attribute NOM_FREQ of OSCHinst0 : label is "12.09";
constant C_CNT_1HZ : natural := 6000000;
signal R_CNT_1HZ : natural range 0 to C_CNT_1HZ := 0;
signal R_1HZ : std_logic := '0';
begin
OSCHInst0: OSCH
-- synthesis translate_off
GENERIC MAP(NOM_FREQ => "12.09")
-- synthesis translate on
PORT MAP (STDBY => '0',
OSC => osc_int -- <= this is the 12.09MHz internal clock from the internal oscillator
);
p_1HZ : process (osc_int) is
begin
if rising_edge(osc_int) then
if R_CNT_1HZ = C_CNT_100HZ-1 then
R_1HZ <= not R_1Hz;
R_CNT_1HZ <= 0;
else
R_CNT_1HZ <= R_CNT_1HZ + 1;
end if;
end if;
end process;
o_led_1 <= R_1HZ when (i_switch_1 = '0') else '0';
end rtl;

VHDL FSM not compiling

I've created the following fsm to control a fir filter but I'm getting two errors while compiling.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
USE ieee.numeric_std.ALL;
entity fsm is
generic (n: integer:=4);
port( clk: in STD_LOGIC;
rst: in STD_LOGIC;
a: out STD_LOGIC_VECTOR(2*n-1 downto 0));
end fsm;
architecture fsm_struct of fsm is
type state_type is (state0, state1, state2);
signal state: state_type;
signal rstff, rom_enable, ram_read_enable, ram_write_enable: STD_LOGIC;
component filter_rom is
generic (n: integer);
port ( clk: in STD_LOGIC;
rstff: in STD_LOGIC;
rom_enable : in STD_LOGIC;
ram_read_enable : in STD_LOGIC;
ram_write_enable : in STD_LOGIC;
a: out STD_LOGIC_VECTOR(2*n-1 downto 0));
end component;
begin
process(clk,rst)
variable delay1:integer:=0;
variable delay2:integer:=0;
variable delay3:integer:=0;
begin
if rst='1' then
state<=state0;
else if rising_edge(clk) then
case state is
when state0 => --initialize & input data
rom_enable<='1';
rstff<='1';
if delay1=1 then
rstff<='0';
state<=state1;
delay2:=0;
else
delay1:=delay1+1;
state<=state0;
end if;
when state1 => --write data to ram
if delay2=2 then
ram_write_enable<='1';
state<=state2;
delay3:=0;
else
delay2:=delay2+1;
state<=state1;
end if;
when state2 => --read data from ram
if delay3=1 then
ram_read_enable<='1';
state<=state0;
delay1:=0;
else
delay3:=delay3+1;
state<=state2;
end if;
end case;
end if;
end process;
filter0: filter_memory generic map(n=>n) port map(clk,rstff,rom_enable,ram_read_enable,ram_write_enable,a);
end fsm_struct;
The errors I'm getting are: Line 83: Syntax error near "process",
Line 85: Syntax error near "generic". at the end of the program. I know that my code won't even compile to any of your machines as my filter is not defined, but I need some help from a fresh set of eyes.
I used 'else if' instead of 'elsif' and it didn't compile.
filter0: filter_memory generic map(n=>n) but your component name is filter_rom
try
filter0: filter_rom generic map(n=>n)
If you changed else if to elsif change it here also.
It compiles in Vivado 2017.4

Wait statement to be synthesizable

I have this problem with the VHDL synthesis. I read in multiple articles that the "wait" statement is synthesizable if I only use one "wait until"/process, so that's what I did. So I tried to make a counter which shows at what floor I am (my project consists of an elevator in Logic Design), and it should open the doors for 5 seconds at floors which were ordered. The problem is with the wait statement. I don't know what to replace it to make it work in ISE too.
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity counter is
port(clk1: in std_logic;
enable2:in std_logic;
input_mux: in std_logic;
dir: in std_logic;
reset,s_g,s_u: in std_logic;
q_open: out std_logic;
q: out std_logic_vector(3 downto 0));
end counter;
architecture c1 of counter is
signal flag: std_logic:='0';
component test
port(clock: in std_logic;
a: in std_logic_vector(3 downto 0);
notify: out std_logic);
end component;
begin
delay: test port map(clk1,"0101",flag);
process
variable temp:std_logic_vector(3 downto 0):="0000";
variable q_open_var:std_logic:='0';
begin
if (enable2='1') then
if (s_g='1' and s_u='1') then
if (RESET='1') then
temp:="0000";
elsif (CLK1'EVENT and CLK1='1') then
if (DIR='1') then
temp:=temp+1;
elsif(DIR='0') then
temp:=temp-1;
end if;
end if;
end if;
end if;
if (input_mux='1') then
q_open_var:='1';
q_open<=q_open_var;
wait until (flag'event and flag='1');
q_open_var:='0';
end if;
q<=temp;
q_open<=q_open_var;
wait on clk1, reset;
end process;
end c1;
Although this structure is supported, you pushed over the limit of what is supported. The synthesis tool must generate registers from what you code. A register does have a clock and a reset input, but the synthesis tool does not know the words clk1 and reset. I.e. is you write
wait on clk1, reset;
The tool will not know what the reset is, nor what the clock is. Actually, both signals are considered clock triggers.
But you design is more problematic, as you have if-statements before the asynchronous reset and clock trigger. Although clock-gating is supported, you probably did not intend it.
Then there is a /second/ clock trigger in you statement: wait until (flag'event and flag='1');. I don't know what you are doing there, but how would you imagine this being realized in hardware?
You should really stick to standard/advised coding style for predictable behavior. I.e.
library ieee;
use ieee.numeric_std.all;
[...]
signal temp : unsigned(3 downto 0) := (others => '0');
begin
temp_proc: process(clk1, reset)
variable q_open_var : std_logic := '0';
begin
if rising_edge(clk1) then
if enable2='1' and s_g='1' and s_u='1' then
if dir = '1' then
temp <= temp + 1;
elsif dir = '0' then
temp <= temp - 1;
end if;
end if;
end if;
if reset = '1' then
temp <= (others => '0');
end if;
end process;
q <= std_logic_vector(temp);
(I left out the q_open part, as it is unclear what you want. Make a SEPARATE process for that, as it is not dependent on reset)
p.s. I like the five lines of end if; the most ;) Please use proper indenting next time. And use 'elsif' not 'else if'.

how to read image file and convert it to bits in vhdl

I am trying to read an image file using textio package in vhdl.
If i open an .jpg with notepad , i will get some junk data but actually it is ASCII data . Here i am trying to read these ascii data and convert them into bytes.
below is my code:
library ieee;
use ieee.std_logic_1164.all;
use std.textio.all;
use ieee.std_logic_textio.all;
entity file_io is
port (
clk: in std_logic;
Data: out std_logic_vector(7 downto 0)
);
end entity;
architecture behav of file_io is
signal test_data : std_logic_vector(7 downto 0);
use ieee.numeric_std.all;
use std.textio.all;
use ieee.std_logic_textio.all;
begin
File_reader:process(clk)
file f : text open read_mode is "C:\Users\Public\Pictures\Sample Pictures\Chrysanthemum.jpg";
variable L: line;
variable var_int: integer:= 0;
variable var_char: character;
begin
if rising_edge(clk) then
while not endfile(f) loop
readline(f, L);
read(L, var_char);
var_int := character'pos(var_char);
test_data <= std_logic_vector(to_unsigned(var_int, test_data'length));
end loop;
end if;
Data <= test_data;
end process;
end architecture behav;
testbench:
LIBRARY ieee;
use ieee.std_logic_1164.ALL;
use std.textio.all;
ENTITY file_io_test IS
END file_io_test;
ARCHITECTURE behavior OF file_io_test IS
use work.io.all;
signal clk: std_logic := '0';
signal Data: std_logic_vector(7 downto 0);
-- Clock period definitions
constant clk_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
UUT:
entity work.file_io(behav)
port map (
clk => clk,
Data => Data
);
-- Clock process definitions( clock with 50% duty cycle is generated here.
clk_process :process
begin
clk <= '1';
wait for clk_period/2; --for 5 ns signal is '1'.
clk <= '0';
wait for clk_period/2; --for next 5 ns signal is '0'.
end process;
end behavior;
I am getting only one byte in waveform. expected result is : Every clock cycle new character should be rread and new byte should be obtained.
below is waveform:
below is the image I am trying to read:
You have a while loop placed inside the rising_edge part of your process. What happens is that when the first clock edge occurs, the while loop iterates until the end of the file and gives you the last byte of the input image.
Removing the while loop statement should solve your issue.
The question has a fundamental flaw. You can't use textio to read binary values, it's for text.
See IEEE Std 1076-2008 16.4 Package TEXTIO paragraphs 3 (in part) and 4:
Procedures READLINE, WRITELINE, and TEE declared in package TEXTIO read and write entire lines of a file of type TEXT. Procedure READLINE causes the next line to be read from the file and returns as the value of parameter L an access value that designates an object representing that line. If parameter L contains a non-null access value at the start of the call, the procedure may deallocate the object designated by that value. The representation of the line does not contain the representation of the end of the line. ...
The language does not define the representation of the end of a line. An implementation shall allow all possible values of types CHARACTER and STRING to be written to a file. However, as an implementation is permitted to use certain values of types CHARACTER and STRING as line delimiters, it might not be possible to read these values from a TEXT file.
And that can be demonstrated with your Chrysanthemum.jpg:
It is possible in VHDL to read raw characters one at a time (matching your need).
See IEEE Std 1076-2008 5.5 File types:
So all we have to do is declare a file type and we get these procedures defined implicitly.
We can use them to invoke raw read, without any end of line issues caused by textio:
library ieee;
use ieee.std_logic_1164.all;
entity file_io is
port (
clk: in std_logic;
Data: out std_logic_vector(7 downto 0);
done: out boolean
);
end entity;
architecture foo of file_io is
use ieee.numeric_std.all;
begin
File_reader:
process (clk)
-- "C:\Users\Public\Pictures\Sample Pictures\Chrysanthemum.jpg";
constant filename: string := "Chrysanthemum.jpg"; -- local to sim
variable char_val: character;
variable status: FILE_OPEN_STATUS;
variable openfile: boolean; -- FALSE by default
type f is file of character;
file ffile: f;
variable char_count: natural := 0;
begin
if rising_edge (clk) then
if not openfile then
file_open (status, ffile, filename, READ_MODE);
if status /= OPEN_OK then
report "FILE_OPEN_STATUS = " &
FILE_OPEN_STATUS'IMAGE(status)
severity FAILURE;
end if;
report "FILE_OPEN_STATUS = " & FILE_OPEN_STATUS'IMAGE(status);
openfile := TRUE;
else
if not endfile(ffile) then
read(ffile, char_val);
-- report "char_val = " & character'image(char_val);
char_count := char_count + 1;
Data <= std_logic_vector (
to_unsigned(character'pos(char_val),
Data'length) );
end if;
if endfile(ffile) then -- can occur after last character
report "ENDFILE, read " &
integer'image(char_count) & "characters";
done <= TRUE;
FILE_CLOSE(ffile);
end if;
end if;
end if;
end process;
end architecture foo;
library ieee;
use ieee.std_logic_1164.all;
entity file_io_test is
end file_io_test;
architecture behavior of file_io_test is
signal clk: std_logic := '0';
signal data: std_logic_vector(7 downto 0);
signal done: boolean;
constant clk_period: time := 10 ns;
begin
uut:
entity work.file_io(foo)
port map (
clk => clk,
data => data,
done => done
);
clk_process:
process
begin
if not done then
clk <= '1';
wait for clk_period/2;
clk <= '0';
wait for clk_period/2;
else
wait;
end if;
end process;
end architecture behavior;
Now we can have all the characters than can delimit a line show up in our read:
Note that package std.textio is not made visible through any context item.

VHDL 'generate' FSM states

I have a variable number of modules linked to another module via a signal bus : std_logic_vector(NUM-1 downto 0), with each component using 8 bits, so that:
bus(7 downto 0) = first module
bus(15 downto 8) = second module
As for creating the instances and doing the port mapping, that is easily done with a
INST: for i in 0 to NUM-1 generate
Inst_module port map ( bus => bus(i*8+7 downto i*8) );
end generate INST;
My question:
I would like to be able to interface with each module via a FSM (since it needs to do some other things too), so would like to be able to 'generate' the following code, rather than having to write out each state manually (Where signal empty : std_logic_vector(NUM-1 downto 0) is a status flag for each module)
type state_type is (st0_idle, st1_work0, st1_work1 --,etc.)
signal state : state_type;
begin
process(empty)
begin
if RESET = '1' then
--reset FSM
state <= st0_idle;
else
if CLK'event and CLK='1' then
case state is
when st0_idle =>
if empty(0) = '0' then
state <= st1_work0;
elsif empty(1) = '1' then
state <= st1_work1;
--etc.
end if;
when st1_work0 =>
bus(7 downto 0) <= SOMETHING;
state <= st0_idle;
when st1_work1 =>
bus(15 downto 8) <= SOMETHINGELSE;
state <= st0_idle;
--etc..
end if;
end if;
end process;
As you can see, there is a lot of repetition. But I can't simply put a for-generate inside the case, so what should I do?
One good way to make processes with state machines more readable is to merge common code into procedures defined within the process. For example:
process (empty) is
procedure assign_something (
index : natural;
something : std_logic_vector(7 downto 0)
next_state : state_type
) is
begin
bus(index*8+7 downto index*8) <= something;
state <= next_state;
end procedure;
begin
wait until rising_edge(clk);
case state is
when st0_idle => ...
when st1_work0 => assign_something(0, something, st0_idle);
when st1_work1 => assign_something(1, something_else, st0_idle);
-- ... etc ...
end case;
if reset = '1' then
state <= st0_idle;
end if;
end procedure;
Hopefully you get the idea. Depending on how regular the state machine structure is, you may also want to replace the enumerated state variables that correspond to each index with a simple count or index variable that you keep track of along with the named state.
That's all up to you, but however you do it, using procedures to factor out common code whenever you can will probably make your VHDL much easier to work with.
Applying this change would make the code look something like this:
architecture ...
type state_type is (st_idle, st_work);
signal state : state_type;
signal index : integer range 0 to NUM-1;
...
begin
...
process (empty) is
procedure assign_something (
index : natural;
something : std_logic_vector(7 downto 0)
next_state : state_type
) is
begin
bus(index*8+7 downto index*8) <= something;
state <= next_state;
end procedure;
begin
wait until rising_edge(clk);
case state is
when st_idle =>
for i in 0 to NUM-1 loop
if empty(i) = '1' then
index := i;
exit;
end if;
end loop;
when st_work => assign_something(index, something, st_idle);
end case;
if reset = '1' then
state <= st_idle;
end if;
end procedure;
Obviously this has to be changed to match exactly what you want to do ... =)

Resources