Greeting All:In VHDL, using a clocked_value in a single process, is it possible to access the next clocked_value, without creating another signal 'next_clocked_value' and controlled in another unclocked process? For instance:
... signal clocked_value : integer; ... process(reset,clock) begin if reset = '0' then clocked_value <= 0; elsif rising_edge(clock) then if <logic-here> then clocked_value <= <logic-here>; elsif <logic-here> then .... end if; end process;Code such as this creates registers which clock out the values as required on the Q port. How do I access the D port, without having to re-write the format. Hardware-wise, the data is available, I haven't found a way to access it in VHDL yet. David K.
Im not quite sure I follow. Why cant you just use "clocked_value"?Why not post a real code example? You have to remember, this is just code - not logic yet, so you need to create all the signals/variables you need to see whatever values at any given time.
Greetings Tricky, and All, as well:My apology for not being clear enough. I'll try being more specific this time... This more of a VHDL coding preference issue for code optimizing, as I know the logic result is available for the designed hardware result, however a single change of the design dramatically changes what is required for the code modification. Or, for instance, a state machine requires, as shown in almost every demonstrations, a clocked process and an unclocked process. This requires having 2 places which need to be identical format, and the desired sequence is controlled in 2 separate places, which makes not-so-readable. Example code snippet, a counter used as a ROM address, with a flag for specific sectors:
... signal count_en : std_logic; signal counter : integer range 0 to 255; signal mem : mem_t := init_mem_values;-- <= not defined for this code demo signal mem_q : integer range 0 to 255; signal segment_flag : integer range 0 to 3;--used to demonstrate a clocked result ... begin Process(reset, clock) begin if reset = '0' then counter <= 0; segment_flag <= 0; elsif rising_edge(clock) then if count_en = '1' then counter <= counter + 1; end if; if counter < 10 then segment_flag <= 0; elsif counter < 29 then segment_flag <= 1; elsif ... end if; end if; end process; process(clock) begin if rising_edge(clock) then mem_q <= mem(counter); end if; end process; ...This has the counter used as the mem address and advances if the count_en is used, and it sends the segment_flag showing the mem_q position, as specified. The mem_q is one clock behind. Now lets desire to have the mem_q is advanced 1 clock sooner, so it will match the count...
... signal count_en : std_logic; signal counter : integer range 0 to 255; signal next_counter : integer range 0 to 255; signal mem : mem_t := init_mem_values;-- <= not defined for this code demo signal mem_q : integer range 0 to 255; signal segment_flag : integer range 0 to 3;--used to demonstrate a clocked result ... begin --unclocked Process(counter) begin next_counter <= 0; --default next_counter <= counter; if count_en = '1' then next_counter <= counter + 1; end if; end process; --clocked Process(reset, clock) begin if reset = '0' then counter <= 0; mem_flag <= 0; elsif rising_edge(clock) then counter <= next_counter; if next_count < 10 then segment_flag <= 0; elsif next_count < 29 then segment_flag <= 1; elsif ... end if; end if; end process; process(clock) begin if rising_edge(clock) then mem_q <= mem(next_counter); end if; end process; ...This hasn't been compiled, ignore any mistakes unless they creates confusion. Here, a simple change to the design makes a dramatic change to organization, and divides the sequence into two separate processed. This could be much more complicated using many separate counters, with many enables to advance them, or a state-machine with many states used. Hardware wise, the change routes the counter's 'D' input to the mem address, rather than the counter's 'Q' output to the mem address. This also does the same for the segment_flag to keep it synced with the mem output. Hypothetically, if there was a VHDL attribute such as counter'next_clk to read the 'D' value as mentioned, to make the change, the attribute would be required in the mem_q(this spot), as well the if-else portion controlling the segment_flag. It wouldn't require doubling signals used, adding an unclocked process, and separating part to each process. I frequently code a project using a single clocked process, until I find one specific issue where I need access the 'D' value to advance a clock value, and the only option I found so far is as shown. And using state machines, I know this in advance, and it's a pain having to generate the sequence in 2 separate places, not in a single sequential place. In Quartus's RTL Viewer, every signal to a register's 'D' port is identified, such as 'counter~18' (more complicated if resets to not all '0') when the counter is only in a single clocked process. That is completely definable based on the entered VHDL code, so I would like to be able access the 'D' value with such as an attribute representing next clocked value, so I can organize my code better, and not have to duplicate processes and many signals. I hopes this an interesting ides. David K.
If I understand what you're saying, then the answer is really you are already doing it the way you need to.This almost feels like the reverse of the problem most newbies have - I think you're visualising your intended circuit in too much detail - VHDL itself has no knowledge of gates and registers - it is the tool that does this conversion. If you really want to get to this level, you can instantiate primitives yourself, but no one else will really want to ever look at your code. So therefore there are no attributes that allow you to access primitive pins, as for some technologies pins may have different names, or not exist at all (remember, VHDL can also map to Xilinx, Atmel, Samsung or any other ASIC vendor primitives, and in theory all from the same code). Try and think behaviour. Having synchronous code and async code is always going to happen. And if your change in behaviour mandates this change, then you have to change the bahaviour of the circuit and hence the code. But have you considered using shorter forms of coding rather than asynchronous processes? something like:
next_counter <= counter + 1 when count_en = '1' else counter;PS> I never code state machines with 2 processes - always a single clocked process.
Tricky:Rats, I was hoping there was something to do that. In VHDL, any clocked signal or variable has the next_reg_value (enumerated, integer, std_logic...), even without it being defined, (the next value is routed to the register's 'D' port), it must be determined in advance, before the clock arrives. That VHDL functionality is applicable to any type or manufacturer's hardware, synthesizable or not, like a testbench. Yes it CAN be defined, as shown in the previous demonstration, and requires a different layout, witch I'm trying to avoid. I used the term <signal name>'attribute since the source value must be accessible by code compilation, and is 100% dependent on the <signal name>, plus logic changes of course, since the signal will hold that value after the clock passes. I searched through as many attribute I could fined, and didn't find anything even close, so I didn't expect it to exist. I guess if I'm the only one who's thought about that, it's unlikely for it to be added to next VHDL version. (I usually stay in '93 version anyway). What is your state_machine secret for configuration to only have a single clocked process? All four state_machine types in the "Insert Template\VHDL\Full Designs\State Machines" path have both clocked and unclocked processes. I don't really consider the "User-Encoded State Machine" having 2 processes configured the same way, since the clocked process has a single clocked assignment. If there were other clocked outputs dependent on the states, they would need to be added to the clocked process, or their own clocked process, with a case state section witch would promote the process to be viewed as a clocked state process. Any suggestions I should check out. David K.
--- Quote Start --- Rats, I was hoping there was something to do that. In VHDL, any clocked signal or variable has the next_reg_value (enumerated, integer, std_logic...), even without it being defined, (the next value is routed to the register's 'D' port), it must be determined in advance, before the clock arrives. That VHDL functionality is applicable to any type or manufacturer's hardware, synthesizable or not, like a testbench. Yes it CAN be defined, as shown in the previous demonstration, and requires a different layout, witch I'm trying to avoid. --- Quote End --- VHDL does not have a "next_reg_value" or anything like that. VHDL Has no concept of, or access to, any underlying hardware, whether it's the D port on a latch, the read address of a memory, or a the enable line on a tri-state buffer. Therefore you need to define a signal for ANYTHING you intend to use inside the code. VHDL is a behavioural language. In simulation it works using a series of delta cycles, which are infinitely small periods of time. When a signal assignment occurs, it only schedules the assignment to take place at the end of the current delta cycle, hence why you can make multiple assignments to a signal and only the last one gets assigned (as opposed to variables, which are assigned immediately). VHDL does have attributes like my_signal'delayed(T) which is a copy of my_signal delayed by time T, but this is a simulation only concept as it would have no meaning in hardware. there is also 'transaction, 'event and 'stable - again, simulation only concepts as they have no meaning in hardware. For a single process state machine, I just do this:
process(clk) begin if rising_edge(clk) then case state is when s1 => state <= s2; when s2 => state <= s3; --etcdoing this means you never accidently create any latches, because everything is clocked. But it will mean some signals may need to be assigned outside of the process if they need to act on the current version of state.