umarcor on keep-compiling
ci: use the built-in '--keep-co… (compare)
umarcor on cosim
cosim/dpi-ffi: add 'vhdpi_ghdl.… cosim/dpi-ffi: add VHDPI_Test (compare)
umarcor on cosim
WIP setenv (compare)
umarcor on main
cosim/dpi-ffi/ghdl-vffi/test: a… (compare)
umarcor on cosim
umarcor on main
WIP envvars (compare)
umarcor on cosim
WIP envvars (compare)
umarcor on master
umarcor on main
umarcor on cosim
umarcor on master
cosim/dpi-ffi: create subdir 'g… cosim/dpi-ffi: fix compilation … cosim/dpi-ffi/ghd-vffi: use VUn… and 2 more (compare)
umarcor on cosim
ci: add workflow CoSim cosim/dpi-ffi: add README (compare)
umarcor on cosim
ci: add workflow CoSim cosim/dpi-ffi: add README (compare)
umarcor on cosim
cosim/dpi-ffi: create subdir 'g… cosim/dpi-ffi: fix compilation … cosim/dpi-ffi/ghd-vffi: use VUn… and 2 more (compare)
umarcor on top-subtype
umarcor on master
2008: ad tb_top_generic_subtype cosim: add ref to aguinet/drago… (compare)
umarcor on top-subtype
2008: ad tb_top_generic_subtype (compare)
umarcor on top-subtype
2008: ad tb_top_generic_subtype (compare)
umarcor on top-subtype
2008: ad tb_top_generic_subtype (compare)
umarcor on style
P2
in the LRM.
package P2 is
generic (
type access_type is access type is private
);
alias designated_subtype is access_type'DESIGNATED_SUBTYPE;
end package;
architecture A of E is
package I2 is new P2
generic map (
access_type => line
);
begin
end architecture;
type t;
is legal as a forward type declaration, but it requires the complete type at a later point in the same unit
package P2 is
generic (
type designated_subtype
);
type fred is access designated_subtype ;
type tricky_pt is new protected pt
generic map (
....
);
It's a (new) type, and no subtype, because instances of PT are not compatible to each other.
either create a library file first, then run ghdl-yosys-plugin on that:
ghdl analyze file1.vhdl file2.vhdl subdir/file3.vhdl
ghdl elaborate topentity
yosys -m ghdl -p 'ghdl topentity'
or run ghdl-yosys-plugin directly on the files, without creating a library file:
yosys -m ghdl -p 'ghdl file1.vhdl file2.vhdl subdir/file3.vhdl -e topentity'
in general, the yosys ghdl
command is equivalent to invoking the ghdl binary as ghdl --synth
.
Actually, there is another solution in-between:
ghdl analyze file1.vhdl file2.vhdl subdir/file3.vhdl
yosys -m ghdl -p 'ghdl -e topentity'
That is useful if the files are analysed in a library different to the top-level, but you don't care about the logical lib name of the top-level:
ghdl analyze --work=designlib file1.vhdl file2.vhdl subdir/file3.vhdl
yosys -m ghdl -p 'ghdl toplevel.vhd -e topentity'
# Synthesis
yosys -m ghdl -p 'ghdl --work=designlib file1.vhdl file2.vhdl subdir/file3.vhdl --work=anyother toplevel.vhd -e topentity'
# Analysis and Elaboration
ghdl -a \
--work=designlib file1.vhdl file2.vhdl subdir/file3.vhdl \
--work=anyother toplevel.vhd testbench.vhd \
-e topentity
# elab-run
ghdl elab-run \
--work=designlib file1.vhdl file2.vhdl subdir/file3.vhdl \
--work=anyother toplevel.vhd testbench.vhd \
-e topentity \
--wave=mywave.ghw
function f return real;
function f return integer is
begin
return integer(real'(f));
end f;
I was on the team that created VHDL. I was probably the first person to actually write VHDL, since my task on the team was to write VHDL and see how usable it was.
inout
ports that are connected together
signal u1_io, u2_io : std_logic_vector(15 downto 0);
followed by u1 : one port map(io => u1_io); u2 : two port map(io => u2_io); u1_io <= transport u2_io after 10 ps; u2_io <= transport u1_io after 10 ps;
is not the way to go
'others
attribute: u1_io <= transport u2_io'others after 10 ps; u2_io <= transport u1_io'others after 10 ps;
sounds like a reasonable syntax, but I'm not sure how well that would translate to three drivers
If you "know" when each chip is driving the bus you could try something like:
p_delays : process(ic1_drive, ic2_drive, ic1_pin_io, ic2_pin_io)
begin
ic1_pin_io <= transport 'Z' after (12 ps);
ic2_pin_io <= transport 'Z' after (13 ps);
if(ic1_drive) then
ic2_pin_io <= transport ic1_pin_io after 9 ps;
end if;
if(ic2_drive) then
ic1_pin_io <= transport ic2_pin_io after 11 ps;
end if;
end process p_delays;
With:
To create ic1_drive and ic2_drive the test bench must look at the control signals in the transaction, and determine what is happening (this may be non trivial).
A quick test seems to be working as expected (there are some quirks when going to X, but it is a starting point).
Note: In this example the testbench drives the ic1_drive and ic2_drive instead of "calculating" them from other signals. But this makes it easier for the proof of concept.
--------------------------------------------------------------------------------
------------------------------------- ENTITY -----------------------------------
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
entity IC is
port(
drive : in std_logic;
clk : in std_logic;
pin_io : inout std_logic
);
end IC;
--------------------------------------------------------------------------------
---------------------------------- ARCHITECTURE --------------------------------
--------------------------------------------------------------------------------
architecture RTL of IC is
signal s_pin_val : std_ulogic := '0';
begin
pin_io <= s_pin_val when (drive = '1') else 'Z';
p_set_out : process (clk)
begin
if rising_edge(clk) then
if(drive = '1') then
s_pin_val <= NOT(s_pin_val);
end if;
end if;
end process p_set_out;
end RTL;
--------------------------------------------------------------------------------
------------------------------------- ENTITY -----------------------------------
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
entity IC_tb is
end IC_tb;
--------------------------------------------------------------------------------
---------------------------------- ARCHITECTURE --------------------------------
--------------------------------------------------------------------------------
architecture testBench of IC_tb is
signal clk : std_logic := '0';
signal ic1_drive : std_logic := '0';
signal ic2_drive : std_logic := '0';
signal ic1_pin_io : std_logic;
signal ic2_pin_io : std_logic;
begin
clk <= NOT(clk) after 50 ps;
p_delays : process(ic1_drive, ic2_drive, ic1_pin_io, ic2_pin_io)
begin
ic1_pin_io <= transport 'Z' after (12 ps);
ic2_pin_io <= transport 'Z' after (13 ps);
if(ic1_drive) then
ic2_pin_io <= transport ic1_pin_io after 9 ps;
end if;
if(ic2_drive) then
ic1_pin_io <= transport ic2_pin_io after 11 ps;
end if;
end process p_delays;
p_stimuli : process
begin
ic1_drive <= '0';
ic2_drive <= '0';
wait for 200 ps;
wait until rising_edge(clk);
ic1_drive <= '1';
wait for 500 ps;
wait until rising_edge(clk);
ic1_drive <= '0';
wait for 500 ps;
wait until rising_edge(clk);
ic2_drive <= '1';
wait for 500 ps;
wait until rising_edge(clk);
ic2_drive <= '0';
wait for 500 ps;
wait until rising_edge(clk);
ic1_drive <= '1';
ic2_drive <= '1';
wait for 500 ps;
wait until rising_edge(clk);
ic1_drive <= '0';
ic2_drive <= '0';
wait; -- !!!!!!!! Forever
end process p_stimuli;
i_ic1 : entity work.IC(RTL)
port map(
clk => clk,
drive => ic1_drive,
pin_io => ic1_pin_io
);
i_ic2 : entity work.IC(RTL)
port map(
clk => clk,
drive => ic2_drive,
pin_io => ic2_pin_io
);
end testBench;