On Saturday, August 2, 2014 5:47:30 AM UTC+12, Mark Curry wrote:
> 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?
You specify a resolution function to use in a subtype indication declaring signals. The simulator provides an array type of the base type of the signal having a value for every driver on the net and calls the function internally.
A resolution function has one argument, an array vector and returns a result that is of the same base type.
This is from package std_logic_1164 for std_logic:
type stdlogic_table is array(STD_ULOGIC, STD_ULOGIC) of STD_ULOGIC;
-------------------------------------------------------------------
-- resolution function
-------------------------------------------------------------------
constant resolution_table : stdlogic_table := (
-- ---------------------------------------------------------
-- | U X 0 1 Z W L H - | |
-- ---------------------------------------------------------
('U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U'), -- | U |
('U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'), -- | X |
('U', 'X', '0', 'X', '0', '0', '0', '0', 'X'), -- | 0 |
('U', 'X', 'X', '1', '1', '1', '1', '1', 'X'), -- | 1 |
('U', 'X', '0', '1', 'Z', 'W', 'L', 'H', 'X'), -- | Z |
('U', 'X', '0', '1', 'W', 'W', 'W', 'W', 'X'), -- | W |
('U', 'X', '0', '1', 'L', 'W', 'L', 'W', 'X'), -- | L |
('U', 'X', '0', '1', 'H', 'W', 'W', 'H', 'X'), -- | H |
('U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X') -- | - |
);
function resolved (s : STD_ULOGIC_VECTOR) return STD_ULOGIC is
variable result : STD_ULOGIC := 'Z'; -- weakest state default
begin
-- the test for a single driver is essential otherwise the
-- loop would return 'X' for a single driver of '-' and that
-- would conflict with the value of a single driver unresolved
-- signal.
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 function resolved;
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).
Further package std_logic_1164 provides To_X01Z conversion functions that can be used to pre-filter std_logic and std_logic_vector values to X01Z values. They are conversion functions (1 input, a return value from a pure function) and functions are expressions ( can be used for example in port map associations) and the result is base type compatible with std_logic.
If you only ever assign 'X', '0', '1' or 'Z' to a standard logic value And you provide a default value that is one of those four values you don't need to do anything to get the same effect as using wor in Verilog.
The To_X01Z functions can be used to filter MVL9 signal values ('U','X','0', '1', 'Z', 'W', 'L','H', '-') to 'X', '0', '1', 'Z' when assignment is out of your control.
VHDL's std_logic_1164 package already provides the functionality you're after.