??? 11/12/06 18:46 Read: times |
#127826 - more work? Responding to: ???'s previous message |
Richard Erlacher said:
The description of the count process is but a small part of the counter. You have to define the "count" as a signal and, outside the process, transfer the "count" to a STD_LOGIC_VECTOR, since XILINX, among others, doesn't support BUFFER mode. Of course, you'd have to support the enable and the reset, wouldn't you? Oh, jeez. First of all, there's rarely ANY reason to put the simple counter into its own counter module, as you probably end up using more lines of code for the counter instantiation than you would use just to describe it. And sometimes the counter (including its enable, reset, load, etc) is embedded in a state machine description because that makes more sense. And you're confusing things here ... a buffer is a direction (like in, out and inout) whereas std_logic_vector is a type. There's nothing saying you can't have an unsigned or signed port, especially with modules that don't drive port pins. Xilinx XST isn't the only synthesizer that doesn't support buffer ports; most HDL experts agree that buffer ports are "broken." And a buffer port isn't the problem with your counter, anyways; you're taking issue with the fact that VHDL (unlike Verilog) doesn't allow a signal declared as a module output to be used on the right-hand-side of an assignment. Here's a cool tip: I pretty much always declare my counters as integers with a specific range; for example: signal counter : integer range 0 to 100;Now, we all know that this will synthesize to a 7-bit counter (actual range 0 to 127) but for internal counting purposes, who cares? In fact, it's useful to take advantage of this in simulation. Test your code and the simulation complains if the counter is assigned, say, 102. Your description indicates the legal values that counter may be assigned and you're told if you're outside the range. But back to the "internal vs external" signal problem. Write your counter using the usual addition operators (well handled by the integer type). If your module uses the counter values for other purposes, like in a comparison, all of the usual operators are available to you (and they AREN'T available when you're using std_logic_vector). So you do all of your work inside the module with the integer type without worrying about casting and such. The only place you do the typecast is the one assignment to the module output port. I also like the unsigned and signed types provided by the numeric_std package. Finally, an easy loadable, clearable counter of arbitrary width. Assume WIDTH is a generic, and initval is a module input of type std_logic_vector(WIDTH-1 downto 0). signal count_i : unsigned (WIDTH-1 downto 0); mycounter : process (clk, arst_l) is begin if (arst_l = '0') then -- async reset count_i <= (others => '0'); elsif rising_edge(clk) begin if (srst = '1') then -- synchronous reset count_i <= (others => '0'); elsif (load = '1') -- synchronous load count <= unsigned(initval); elsif (enable = '1') then if (count_i = (others => '1') then -- gracefully handle overflow count_i <= (others => '0'); else count_i <= count_i + 1; end if; end if; -- enable/reset/load? end if; -- clock edge end process mycounter; countout <= std_logic_vector(count_i); Yeah, more complicated, perhaps, than pulling a counter symbol from your schematic library, but does the library have parametrized width? -a |