Wired Or in VHDL

On Saturday, 2 August 2014 12:45:10 UTC+8, Dio Gratia wrote:

Additionally if you were to look at the truth table for wor and trior in the 1064 (Verilog) standard you'd find that wor works identically to using the std_ulogic subtype X01Z (which is also resolved, using the same resolution function shown above).

Sorry, does the Verilog wor resolve '0' and '1' to an 'X'? Or will it be resolved to a '1'?

-dan
 
On Saturday, August 2, 2014 9:21:37 PM UTC+12, Daniel Kho wrote:

Sorry, does the Verilog wor resolve '0' and '1' to an 'X'? Or will it be
resolved to a '1'?


Opps! Wrong table, Dan is right. My bad.

4-4 from 1364-2005:

wor/trior 0 1 x z
0 0 1 x 0
1 1 1 1 1
x x 1 x x
z 0 1 x z

std_logic matches 4-2, wire/tri.

Which says yes a different resolution function for wor, and begs the question of
who can synthesize logic from single rail transfer gate models in VHDL.

A demo case for penance:

library ieee;
use ieee.std_logic_1164.all;

package wor_stuff is

type wortrior is ('X', '0', '1', 'Z');
type wortrior_vector is array (natural range <>) of wortrior;

function wor_trior (s: wortrior_vector) return wortrior;

subtype wor is wor_trior wortrior;
type wor_vector is array (natural range <>) of wor;

function wor_image(inp: wor_vector) return string;

end package;

package body wor_stuff is

type wor_table is array (wortrior, wortrior) of wortrior;

constant resolution_table : wor_table := (
-- --------------------------------
-- | X 0 1 Z | |
-- --------------------------------
('X', 'X', '1', 'X'), -- | X |
('X', '0', '1', '0'), -- | 0 |
('1', '1', '1', '1'), -- | 1 |
('X', '0', '1', 'Z') -- | Z |
);

function wor_trior ( s: wortrior_vector ) return wortrior is
variable result: wortrior := 'Z';
begin
if (s'length = 1) then return (s(s'low));
else
for i in s'range loop
result := resolution_table(result, s(i));
end loop;
end if;
return result;
end wor_trior;

function wor_image(inp: wor_vector) return string is
variable image_str: string (1 to inp'length);
alias input_str: wor_vector (1 to inp'length) is inp;
begin
for i in input_str'range loop
image_str(i) := character'VALUE(wortrior'IMAGE(input_str(i)));
end loop;
return image_str;
end;

end package body;

library ieee;
use ieee.std_logic_1164.all;
use work.wor_stuff.all;

entity cpu_reg_dummy is
generic ( value: wor_vector(3 downto 0) := (others => 'Z') );
port ( rddata_o: out wor_vector(3 downto 0) );
end entity;

architecture foo of cpu_reg_dummy is

begin
rddata_o <= value after 0.5 ns;
end architecture;

library ieee;
use ieee.std_logic_1164.all;
use work.wor_stuff.all;

entity foo is
end entity;

architecture fum of foo is

component cpu_reg_dummy
generic ( value: wor_vector(3 downto 0) := (others => 'Z') );
port ( rddata_o: out wor_vector(3 downto 0) );
end component;

signal rddata_o: wor_vector (3 downto 0);

begin

CPU_REG1:
cpu_reg_dummy
generic map (value => "0000")
port map (rddata_o => rddata_o);

CPU_REG2:
cpu_reg_dummy
generic map (value => "1001")
port map (rddata_o => rddata_o);

CPU_REG3:
cpu_reg_dummy
generic map (value => "ZZZZ")
port map (rddata_o => rddata_o);

CPU_REG4:
cpu_reg_dummy
generic map (value => "ZZZX")
port map (rddata_o => rddata_o);

WHAT:
process
begin
wait for 0.6 ns;
report "rddata_o = " & wor_image(rddata_o);
wait;
end process;
end architecture;

Which analyzes, elaborates and simulates the test case foowith the following
assertion output:

** Note: 600ps+0: Report Note: rddata_o = 1001
Process :foo:what
File wor.vhdl, Line 113

(and yes the resolution function wor_trior is shamelessly derived from package
std_logic_1164's resolution function).
 
In article <afcfd1a5-253b-4c9f-afca-2c988db6960f@googlegroups.com>,
Daniel Kho <daniel.kho@gmail.com> wrote:
On Saturday, 2 August 2014 01:47:30 UTC+8, Mark Curry wrote:
Sorry, should have been more clear. Those are all just instaciations.

The "multiple driver" read_data is all within `BUS_CONNNECT.

To expand it (leaving some connections out to synplify):



wor rddata_o;

cpu_reg cpu_reg1 ( .addr_i( addr_i ), .cs_i( cs_i ), .wrdata_i( wrdata_i ), .rwn_i( rwn_i ), .rddata_o( rddata_o ) );

cpu_reg cpu_reg2 ( .addr_i( addr_i ), .cs_i( cs_i ), .wrdata_i( wrdata_i ), .rwn_i( rwn_i ), .rddata_o( rddata_o ) );

cpu_reg cpu_reg3 ( .addr_i( addr_i ), .cs_i( cs_i ), .wrdata_i( wrdata_i ), .rwn_i( rwn_i ), .rddata_o( rddata_o ) );



rddata_o has multiple drivers. I want them resolved like a verilog 'wor', but

in VHDL. I'm having trouble figuring out how to tie the VHDL "resolution function" "resolved_wor"

to the single net "rddata_o". "rddata_o" is both the input, and output of the function...

How do I hook it up?



--Mark


architecture rtl of test is
signal rddata_o:resolved_wor std_ulogic;

/* declare the other internal non-resolved signals here (addr_i,
cs_i, wrdata_i, rwn_i).
*/

begin
cpu_reg1: entity work.cpu_reg(rtl) port map(addr_i=>addr_i, cs_i=>cs_i, wrdata_i=>wrdata_i, rwn_i=>rwn_i, rddata_o=>rddata_o);

cpu_reg2: entity work.cpu_reg(rtl) port map(addr_i=>addr_i, cs_i=>cs_i, wrdata_i=>wrdata_i, rwn_i=>rwn_i, rddata_o=>rddata_o);

cpu_reg3: entity work.cpu_reg(rtl) port map(addr_i=>addr_i, cs_i=>cs_i, wrdata_i=>wrdata_i, rwn_i=>rwn_i, rddata_o=>rddata_o);

end architecture rtl;

Here all the 3 entity instances (cpu_reg1, cpu_reg2, cpu_reg3) will be driving the single resolved wire "rddata_o". The resolved_wor resolution function will be used to resolve the multiple drivers.

Of course, you can have more instances driving the net, without needing to specify the array width (or the number of drivers) into the resolution function, provided your function does not constrain
the input argument's width.

To write the resolution function 'resolved_wor', you can use the examples Dio or I provided earlier. Just place it within a VHDL package, and remember to add a library-use clause to 'import' this
package into your design.

Dan, and all.

Thanks for the detailied example (and having the patience to beat its use thru my thick skull).

That is indeed a useful tool in the language. I'm going to play around with this
when I get some time, and see what the tool support is like.

Thanks,

Mark
 

Welcome to EDABoard.com

Sponsor

Back
Top