David wrote: I really do not see the use of physical types in general anyway. I’ll try to present some use cases for physical types in simulation as well as in synthesis. I created a VHDL package called ‘physical’, which defines three new types: - FREQ (frequency), - BAUD (baud rate), - MEMORY (memory size) In the next step I defined several function for: - type conversion, e.g. to_time(freq), to_real(time, scale) - operations, e.g. div(a, b) - high level computations, e.g. TimingToCycles(time, freq) - report functions, e.g. to_string(freq) My projects make heavily use of these types and functions. It eases the handling of generic parameters and allows you to reduce documentation, because of parameter self documentation. This package is tested with several tool chains from different vendors. As you can see in the external source (see link below) the current code if blown up to: - handle physical types correctly in tools, which restrict TIME to 31 bit This can be solved by pre- and post scaling the operands in the div(a, b) functions. - support tools that don’t support femto-second resolutions in TIME some simulators use a more coarse time resolution e.g. pico-seconds sometimes this default can be changed by setting an addition command line parameter - cope overload problems when defining a new div operation, so I’m using functions internal to the package https://code.google.com/p/picoblaze-library/source/browse/vhdl/lib_PoC/physical.vhdl?name=release Use case 1 – A generic PWM generator This generic PWM generator can be configure with - a system frequency, e.g. 100 MHz - a required PWM output frequency, e.g. 1 kHz - the granularity of PWM steps, e.g. 256 steps This component automatically calculates: - the maximum value for the internal counter - the required bits to store this value Now it’s possible to use this component on a 50 MHz board as well as on a 200 MHz board, by changing the system frequency in the top most component of the design. Even if you have multiple clock domains and decide to move such a component to another clock domain, you have only to change one constant. entity io_PulseWidthModulation is generic ( CLOCK_FREQ : FREQ := 100.0 MHz; PWM_FREQ : FREQ := 1.0 kHz; PWM_RESOLUTION : POSITIVE := 8 ); port ( Clock : in STD_LOGIC; Reset : in STD_LOGIC; PWMIn : in STD_LOGIC_VECTOR(PWM_RESOLUTION - 1 downto 0); PWMOut : out STD_LOGIC ); end; architecture rtl of io_PulseWidthModulation is constant PWM_STEPS : POSITIVE := 2**PWM_RESOLUTION; constant PWM_STEP_FREQ : FREQ := PWM_FREQ * real(PWM_STEPS - 1); constant PWM_FREQUENCYCOUNTER_MAX : POSITIVE := TimingToCycles(to_time(PWM_STEP_FREQ), CLOCK_FREQ); constant PWM_FREQUENCYCOUNTER_BITS : POSITIVE := log2ceilnz(PWM_FREQUENCYCOUNTER_MAX); signal PWM_FrequencyCounter_us : UNSIGNED(PWM_FREQUENCYCOUNTER_BITS downto 0) := (others => '0'); signal PWM_FrequencyCounter_ov : STD_LOGIC; signal PWM_PulseCounter_us : UNSIGNED(PWM_RESOLUTION - 1 downto 0) := (others => '0'); signal PWM_PulseCounter_ov : STD_LOGIC; Use case 2 – an I²C controller I²C defines different timings for different bus speeds. So I encoded these timings in functions like getBusFreeTime: function getBusFreeTime(IIC_BUSMODE : T_IO_IIC_BUSMODE) return TIME is begin if SIMULATION then return 500.0 ns; end if; case IIC_BUSMODE IS when IO_IIC_BUSMODE_SMBUS => return 4700.0 ns; when IO_IIC_BUSMODE_STANDARDMODE => return 4700.0 ns; when IO_IIC_BUSMODE_FASTMODE => return 1300.0 ns; when IO_IIC_BUSMODE_FASTMODEPLUS => return 500.0 ns; when IO_IIC_BUSMODE_HIGHSPEEDMODE => return 0.0 ns; when others => return 0.0 ns; end case; end function; In the next step I transformed these timings (I²C has 10 timings, so I needed 10 functions) into a single array of delay values (called TIMING_TABLE). -- Timing table constant TIMING_TABLE : T_NATURAL_VECTOR := ( TTID_BUS_FREE_TIME => TimingToCycles(TIME_BUS_FREE, CLOCK_FREQ), TTID_HOLD_CLOCK_AFTER_START => TimingToCycles(TIME_HOLD_CLOCK_AFTER_START, CLOCK_FREQ), TTID_CLOCK_LOW => TimingToCycles(TIME_CLOCK_LOW, CLOCK_FREQ), TTID_CLOCK_HIGH => TimingToCycles(TIME_CLOCK_HIGH, CLOCK_FREQ), TTID_SETUP_REPEAT_START => TimingToCycles(TIME_SETUP_REPEAT_START, CLOCK_FREQ), TTID_SETUP_STOP => TimingToCycles(TIME_SETUP_STOP, CLOCK_FREQ) ); In the final step this array is passed as a generic parameter to a TimingCounter component, which is efficiently implemented for LUT-6 FPGA architectures. Use case 3 – UART As I described above, there is also a baud rate type. This type is used to calculate the required frequency to drive a clock enable signal for a UART component, which performs a 16x oversampling. constant UART_OVERSAMPLING_RATE : POSITIVE := 16; constant TIME_UNIT_INTERVAL : TIME := 1.0 sec / (to_real(BAUDRATE, 1.0 Bd) * real(UART_OVERSAMPLING_RATE)); constant BAUDRATE_COUNTER_MAX : POSITIVE := TimingToCycles(TIME_UNIT_INTERVAL, CLOCK_FREQ); constant BAUDRATE_COUNTER_BITS : POSITIVE := log2ceilnz(BAUDRATE_COUNTER_MAX + 1); I hope these are three convincing use cases for physical types in everyday life :) So YES, we need 64 bit for physical types. Regards Patrick Lehmann From: owner-vhdl-200x@eda.org [mailto:owner-vhdl-200x@eda.org] On Behalf Of David Smith Sent: Thursday, January 08, 2015 11:54 PM To: vhdl-200x@eda.org Subject: RE: [vhdl-200x] Proposal for improved physical types Since almost all numerical calculations are done with 64 bit real (as opposed to 64 bit integer) I think the loss of precision is not real important (unless you are doing DSP work and then the world is different). It is NOT correct to say that VHDL-AMS supports real based physical types. There are no such things. There are quantities but those are a completely different beast. Both VHDL-AMS and VHDL support a real data type. VHDL-AMS supports a real data type plus a unit. That is the quantity. The quantity is then used only in the solution of analogy equations. The real data type is still used by processes (as is the physical type). We could do an extension to the real type to include a unit and a multiplier where the unit and multiplier are defined in terms of a base unit. That would allow for SI type units on real numbers. I really do not see the use of physical types in general anyway. They seem to be more of a nuisance than a benefit. They define a unit and multiplier for integral numbers. Fun. If we did the same for real numbers then it would make things symmetric and more consistent. Anyway, just some thoughts from the VHDL-AMS side of the world (for about 25 years). Regards David From: owner-vhdl-200x@eda.org<mailto:owner-vhdl-200x@eda.org> [mailto:owner-vhdl-200x@eda.org] On Behalf Of Kevin Thibedeau Sent: Thursday, January 08, 2015 2:41 PM To: vhdl-200x@eda.org<mailto:vhdl-200x@eda.org> Subject: Re: [vhdl-200x] Proposal for improved physical types The idea is to upgrade the existing system for physical types in the least disruptive way. VHDL-AMS does permit real-based physical types in addition to integer. Backporting that into VHDL would be more complex than this proposal although it wouldn't preclude such a change. You do lose some precision with a 64-bit real having only a 53-bit significand. That could cause unexpected results when dealing with large magnitude numbers but it would be a viable option for most use cases. -- Kevin Thibedeau On Thu, Jan 8, 2015 at 5:20 PM, David Smith <David.Smith@synopsys.com<mailto:David.Smith@synopsys.com>> wrote: Why not a physical unit that is actually real based. What is the rationale for limiting physical quantities to integral multipliers of a base type? The physical type consists of a base unit, a multiple to the base unit, and a number. For Time I understand that usefulness of integral time for the efficiency of the event handling. Why the same limitation for a type such as frequency or resistenace, or etc…? Regards David From: owner-vhdl-200x@eda.org<mailto:owner-vhdl-200x@eda.org> [mailto:owner-vhdl-200x@eda.org<mailto:owner-vhdl-200x@eda.org>] On Behalf Of Kevin Thibedeau Sent: Thursday, January 08, 2015 1:42 PM To: vhdl-200x@eda.org<mailto:vhdl-200x@eda.org> Subject: [vhdl-200x] Proposal for improved physical types The current implementation of user defined physical types in VHDL is tied to the implementation of integer which is a problem with most tools only supporting 32-bit integers. The 31-bit positive range of the typical integer only covers nine orders of magnitude or three SI prefixes. This severely restricts the practicality of user defined physical types. The built-in time type is typically implemented as a 64-bit integer, covering a much more useful eighteen orders of magnitude. I would like to propose a system where a new integral subtype "physical" is provided that is guaranteed to cover the same range as the built-in time type. It would be restricted to use only in definitions of physical types to eliminate problems with using it directly as a separate integral type in other contexts. -- Implicit subtype to be defined in std.standard subtype physical is $UNIVERSAL_INTEGER range time'pos(time'low) to time'pos(time'high); While VHDL permits larger integers, at this point many tool vendors are retrenched in their restriction to 32-bit implementations. It seems unlikely that this status quo will ever change due to concerns about backward compatibility. Such a situation doesn't exist for physical types which, in general, have seen limited use. The machinery for handling 64-bit time already exists in most, if not all, current tools so it would not be an undue burden to extend that to other physical types. All of the implicit operators would work as they do with time. By implementing this through a new special purpose subtype, existing code using integer as the basis for physical types will be unaffected. With today's tools one must compromise between precision and maximum range when defining a physical type: -- Definition of a "frequency" physical type using today's tools type frequency is range 0 to integer'high units Hz; kHz = 1000 Hz; MHz = 1000 kHz; GHz = 1000 MHz; -- Usually limited to 2**31 = 2.1 GHz end units; We can make the primary unit kHz to extend the range while sacrificing the ability to represent low frequencies: type frequency is range 0 to integer'high units kHz; MHz = 1000 kHz; GHz = 1000 MHz; THz = 1000 GHz; -- Now support up to 2.1 THz end units; It would be nice to have support for mHz or better precision for more accurate representation of fractional frequencies. Using current implementations, though, a primary unit of mHz would limit the maximum frequency to 2.1 MHz which is too low for many practical uses of a frequency type. With a 64-bit integer for physical types we can define a more useful frequency type that permits large values as well as accurately representing fractional frequencies: -- Implicit subtype to be defined in std.standard subtype physical is $UNIVERSAL_INTEGER range time'pos(time'low) to time'pos(time'high); type frequency is range 0 to physical'high units uHz; milliHz = 1000 uHz; Hz = 1000 milliHz; kHz = 1000 Hz; MHz = 1000 kHz; GHz = 1000 MHz; THz = 1000 GHz; -- Up to 9.2 THz with a 63-bit positive range end units; -- Using "physical" elsewhere is prohibited variable not_allowed : physical; type invalid_array is array(physical'range) of bit; Having special rules for when a type can be used subverts the purity of the type system but I think it is a reasonably pragmatic solution in light of the benefits it would provide. -- Kevin Thibedeau -- This message has been scanned for viruses and dangerous content by MailScanner<http://www.mailscanner.info/>, and is believed to be clean. -- This message has been scanned for viruses and dangerous content by MailScanner<http://www.mailscanner.info/>, and is believed to be clean. -- This message has been scanned for viruses and dangerous content by MailScanner<http://www.mailscanner.info/>, and is believed to be clean. -- This message has been scanned for viruses and dangerous content by MailScanner<http://www.mailscanner.info/>, and is believed to be clean. -- This message has been scanned for viruses and dangerous content by MailScanner, and is believed to be clean.Received on Tue Jan 13 09:58:01 2015
This archive was generated by hypermail 2.1.8 : Tue Jan 13 2015 - 09:58:44 PST