Probably an easy one, but has been a while since I've dabbled in VHDL, but I'm trying to figure out how to properly change generic values of a sub-component after instantiation, when an event happens. Some pseudo code is below that jumps to the point:
U1: PARITY
generic map (N => 8)
port map (A => DATA_BYTE,
ODD => PARITY_BYTE);
....
process(Some_button_click)
begin
// Change generic map value for N (integer) in PARITY to 10 //
end process;
I'm not in front of the code, but I've tried using 'shared variables' to no avail.... any help is greatly appreciated as this has been strangely hard to google.
I understand what you want to do, but as far as I understand generics are mean to be used only to make components reusable and flexible. It does not make sense to change a constant value at run time. My suggestion is that if you need to change the value you better use a signal port
Related
I have a group of 19 bits with each bit having a specific meaning ( a group of flags ). I would like to label each of these bits so they are identified within the simulator with their label.
These bits are read over a communications interface, and when I get them, they are in std_logic_vector value something like this:
signal myflags : std_ulogic_vector(18 downto 0);
I am new to VHDL, but I think the proper procedure for this is to create an enumerated type, but I am not exactly sure how to do this. I have created enumerated types for state machine signals, but the enumeration of each state "label" is just the next numeric value (0,1,2,3, etc). This is not what I want to do. Instead, I want each bit specifically enumerated (or at least a label assigned to each bit).
Really, this would not even come up as an issue if ModelSim would allow me to change the displayed value for a bit. The example below shows my desire to change the Display Name from (31), bit 31 in a std_ulogic_vector value, to "power_good". Any advice would be appreciated.
I am working in a TOP file of a project in VHDL. I have a problem-question concerning the port mapping.
Below, is a part of the code that I am trying to implement and afterwards the description of the context.
generate_microfib:
for i in 0 to 5 generate
fib: microfib
Port Map (
InL => SignalNumber(num(i)*2 + i), --Input Left
OutR => SignalNumber(num(i)*2 + i+1) --Output Right
);
end generate generate_microfib;
The code above creates multiple components of microfib. The microfib, has an input and an output port. What I want to do is connect the left input of the current created component with the right output of the previous created one.
My initial thought was to do it inside the port mapping, but VHDL doesn't give many options for calculations in the for..generate statement. So, I decided to do it in two steps. Meaning that, I first create the desired components and afterwards do the connections (by setting the desired signals equal).
So, my question is: Is it possible to do the connections in a function for example, by setting:
SignalNumber(i)=SignalNumber(i-1)?
I know that the '<=' operator is accepted and not the '=' but I want to show you that my goal is to make those two signals equal and not assign the value of the one to the other.
When I've done things like this, I've used an array-type signal to act as an intermediate placeholder. Then, within the generate loop, you can connect the ports to the indexed locations on the array signal.
So you could try something like this, using std_ulogic as an example port type:
architecture rtl of entity is:
constant N_DEVICES : integer := 5;
signal port_connector : std_ulogic vector(N_DEVICES downto 0);
begin
-- Concurrent statements
generate_microfib : for i in N_DEVICES-1 downto 0 generate
fib : microfib
port map (
InL => port_connector(i+1)
OutR => port_connector(i)
)
end generate generate_microfib;
-- Other stuff
end architecture rtl;
Then, port_connector(N_DEVICES) acts as the input to the chain, and port_connector(0) acts as the output from the chain.
This isn't a function, but it is (relatively) clean and avoids too much of a headache with the generate statement. Functions in VHDL, though, are meant to produce calculated values, not circuit connections, so I would recommend against trying for that anyhow.
I've just started VHDL and its proving to be more difficult than I gave it credit for. At the moment im trying to get my head around the 'generic' area of operation. I've cut down my code as much as possible (this extract doesn't do anything but still produces the error) and still haven't managed to crack it. If one of you could help I would be very greatful!
thanks in advance.
library IEEE;
entity ALU is
GENERIC (constant cst:integer range 15 downto 0);
end ALU;
architecture behavioural of ALU is
begin
End behavioural;
.
error:entity "alu" cannot be at the top of a design
alu.vhdl:6:19: generic "cst" has no default value
I'm searching the verilog equivalent of the VHDL attribute my_signal'last_eventbut in Verilog. I have googled it without success. Does someone know how to do it ?
The 'last_event attribute is used to know the time since the signal last event.
For example, if at time 15us, signal toto toogles from 0 to 1.
Then at time 20us, toto'last_event returns 5us.
Have you tried looking into some of the verilog system tasks? Specifically the following:
$time; // Return current simulation time in 64-bit integer
$monitor("format", v1, v2, ...); // Invoke only once, and execute (
// automatically when any of the
// variables change value.
You can look at the 'nested-if-else-if' example here http://www.asic-world.com/verilog/vbehave2.html for an example of a test bench that uses these.
You could create a time variable and update it whenever the signal changes
time my_signal_last_change;
always #(my_signal) begin
my_signal_last_change = $time;
end
This works in SystemVerilog; not sure if it would in verilog (you can try changing time to reg[63:0] in case it doesn't)
I am preparing for an exam by going through some old ones. One of the questions is:
Write the synthesizable behavioral VHDL code that implements the synchronous FSM in fig...
The FSM has one input, called request, that is of enumeration type with values (r1, r2, r3)...
That makes me want to write this code:
entity fsm is
port ( clk : in std_logic;
request : in my_enum_type
);
end fsm;
And somewhere have a:
type my_enum_type is (r1, r2, r3);
somewhere (I have tried right befor the port declaration and right after the architecture declaration).
But I can't seem to get that to work.
Can I have custom types as inputs or outputs like that?
Yes you can, and I regard it as best practice - it means least work, best understanding, easiest maintenance, and cleanest design.
The trick is to declare the types common to your whole design in a package (I usually call it "Common" :-) and add use work.Common.all before the entity declaration AND in every customer of that entity. More specialised components can have appropriate names, of course!
For example:
package Common is -- untested...
type my_enum_type is (r1, r2, r3);
-- (optional) useful tools
function to_slv (e : my_enum_type) return std_logic_vector;
function to_enum (s : std_logic_vector(my_enum'length downto 0))
return my_enum_type;
end Common;
package body Common is
-- subprogram bodies here
end Common;
Now when you add a value to the enumeration, you ONLY modify "Common" and rebuild the design, while those who follow conventional guidelines are still trying to identify every port and signal where they have to increase the range of their "std_logic_vector" by 1.
Works really well for bus interfaces too, where a record in each direction hides all the individual bus and handshaking signals.
You WILL have to fight brain-dead tools like Xilinx "automatic testbench generator" which will helpfully translate ALL your port types - integer or boolean as well as custom - into std_logic(_vector) and then fail to compile. Just translate them back again.
You can still make a case that at the very top level, all the external FPGA pins should still be std_logic based. And if you ever need to simulate a post-synthesis version of your design, then you will either need to live with std_logic_vector ports, or add a simple wrapper to convert from one form to the other.