??? 06/19/08 21:23 Read: times |
#156049 - re: readability Responding to: ???'s previous message |
Richard said:
There are several ways of performing type conversions in VHDL, but what I'm after is something that won't illicit a response of, "Hey, what's this???" which is what I get when they see
... IF (COUNT = SLV_CONST (84336, 17)) I suppose that if that was one of the standard conversion functions, you would not elicit that response, because anyone conversant in VHDL would understand immediately. If someone could suggest a way of doing the equivalent where it doesn't fall in the middle of the "meat" of a process that otherwise would be fully transparent, I'd be really interested. My example was intended to suggest a way of doing what you ask. Basically, don't use std_logic_vectors except at the "edges" (I/O ports) where they are (defacto) required. In the example you provided, Andy, there's no output other than TERMCNT. If, however, you wanted the count bits as output, a different approach would be needed, and that would entail a type conversion. What I find frustrating is that I've so far been unable to find a thorough description of how that should be done. As with most things in VHDL, I'm sure there are numerous ways. OK, you do the type conversion at the port interface. To wit: library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity counter is generic ( CWIDTH : natural := 16); port ( clk : in std_logic; rst : in std_logic; cval : out std_logic_vector(CWIDTH-1 downto 0); tc : out std_logic); end entity counter; architecture mycounter is -- the subtype conveniently constrains our counter to fit -- in the number of bits allowed. -- if TERMCNT is defined as a number larger than the range, -- you get a compile-time error. -- The main point here is that everything in the entity is -- dealt with as a decimal. subtype count_t : natural range 0 to (2**CWIDTH)-1; signal count : count_t; constant TERMCNT : count_t = 12345; TheCounter : process (clk) is begin ClkEdge: if rising_edge(clk) then isReset : if (rst = '1') then tc <= '0'; count <= 0; else isTermCnt : if count = TERMCNT then tc <= '1'; count <= 0; else tc <= '0'; count <= count + 1; end if isTermCnt; end if isReset; end if ClkEdge; end process TheCounter; -- Convert the counter to a std_logic_vector for the -- outside world. We use a conversion function and a type -- cast, as there is no direct path between integer and SLV. -- The function to_unsigned() converts the integer or -- natural to the unsigned type, which is a vector. This -- function needs to know the size of its result, so to avoid -- hardcoding, use the 'length signal attribute. -- The cast to std_logic_vector works because SLV and -- unsigned are "closely related." cval <= std_logic_vector(to_unsigned(count, cval'length)); end architecture mycounter; BTW, does that count process work without rst in the sensitivity list? Yes, it absolutely works because it implements a synchronous reset, not an async reset. Because it is a synchronous process, the only signal needed on the sensitivity list is the clock, as the clock is the only signal upon which anything happens. If you were to rewrite it to use an asynchronous reset, then you must add the reset to the sensitivity list, and again, those two signals are the only signals on the list. Of course if you were writing a combinatorial process, then ALL signals that appear on the right-hand-side of any equation in that process must be on the list. -a |