Initial commit
This commit is contained in:
19
Libs/AhbLite/hdl/ahbDecoder_RTL.vhd
Normal file
19
Libs/AhbLite/hdl/ahbDecoder_RTL.vhd
Normal file
@ -0,0 +1,19 @@
|
||||
LIBRARY AhbLite;
|
||||
USE AhbLite.ahbLite.all;
|
||||
|
||||
ARCHITECTURE RTL OF ahbDecoder IS
|
||||
BEGIN
|
||||
|
||||
decodeAddress: process(hAddr)
|
||||
variable mask: unsigned(hAddr'range);
|
||||
begin
|
||||
hSel <= (others => '0');
|
||||
for index in hSel'range loop
|
||||
mask := to_unsigned(ahbMemoryLocation(index).addressMask, mask'length);
|
||||
if (hAddr and mask) = ahbMemoryLocation(index).baseAddress then
|
||||
hSel(index) <= '1';
|
||||
end if;
|
||||
end loop;
|
||||
end process decodeAddress;
|
||||
|
||||
END ARCHITECTURE RTL;
|
59
Libs/AhbLite/hdl/ahbLite_pkg.vhd
Normal file
59
Libs/AhbLite/hdl/ahbLite_pkg.vhd
Normal file
@ -0,0 +1,59 @@
|
||||
LIBRARY ieee;
|
||||
USE ieee.std_logic_1164.all;
|
||||
|
||||
PACKAGE ahbLite IS
|
||||
------------------------------------------------------------------------------
|
||||
-- bus components sizes
|
||||
constant ahbAddressBitNb : positive := 16;
|
||||
constant ahbDataBitNb : positive := 16;
|
||||
constant ahbSlaveNb : positive := 16;
|
||||
|
||||
constant ahbTransBitNb : positive := 2;
|
||||
constant ahbSizeBitNb : positive := 1;
|
||||
constant ahbBurstBitNb : positive := 3;
|
||||
constant ahbProtBitNb : positive := 4;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- bus data vector type
|
||||
subtype ahbDataType is std_logic_vector(ahbDataBitNb-1 downto 0);
|
||||
type ahbDataVector is array(1 to ahbSlaveNb) of ahbDataType;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- address decoder
|
||||
type ahbMemoryLocationType is
|
||||
record
|
||||
baseAddress: natural;
|
||||
addressMask: natural;
|
||||
end record;
|
||||
type ahbMemoryLocationVector is array(1 to ahbSlaveNb) of ahbMemoryLocationType;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- bus signals
|
||||
subtype transferType is std_ulogic_vector(ahbTransBitNb-1 downto 0);
|
||||
constant transIdle : transferType := "00";
|
||||
constant transBusy : transferType := "01";
|
||||
constant transNonSeq: transferType := "10";
|
||||
constant transSeq : transferType := "11";
|
||||
|
||||
subtype transferSizeType is std_ulogic_vector(ahbSizeBitNb-1 downto 0);
|
||||
constant size8 : transferSizeType := "0";
|
||||
constant size16 : transferSizeType := "1";
|
||||
|
||||
subtype burstType is std_ulogic_vector(ahbBurstBitNb-1 downto 0);
|
||||
constant burstSingle : burstType := "000";
|
||||
constant burstIncr : burstType := "001";
|
||||
constant burstWrap4 : burstType := "010";
|
||||
constant burstIncr4 : burstType := "011";
|
||||
constant burstWrap8 : burstType := "100";
|
||||
constant burstIncr8 : burstType := "101";
|
||||
constant burstWrap16 : burstType := "110";
|
||||
constant burstIncr16 : burstType := "111";
|
||||
|
||||
subtype protectionType is std_ulogic_vector(ahbProtBitNb-1 downto 0);
|
||||
constant protDefault : protectionType := "0011";
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- log2
|
||||
function addressBitNb (addressNb : natural) return natural;
|
||||
|
||||
END ahbLite;
|
15
Libs/AhbLite/hdl/ahbLite_pkg_body.vhd
Normal file
15
Libs/AhbLite/hdl/ahbLite_pkg_body.vhd
Normal file
@ -0,0 +1,15 @@
|
||||
PACKAGE BODY ahbLite IS
|
||||
|
||||
function addressBitNb (addressNb : natural) return natural is
|
||||
variable powerOfTwo, bitNb : natural;
|
||||
begin
|
||||
powerOfTwo := 1;
|
||||
bitNb := 0;
|
||||
while powerOfTwo <= addressNb loop
|
||||
powerOfTwo := 2 * powerOfTwo;
|
||||
bitNb := bitNb + 1;
|
||||
end loop;
|
||||
return bitNb;
|
||||
end addressBitNb;
|
||||
|
||||
END ahbLite;
|
70
Libs/AhbLite/hdl/ahbMasterInterface_RTL.vhd
Normal file
70
Libs/AhbLite/hdl/ahbMasterInterface_RTL.vhd
Normal file
@ -0,0 +1,70 @@
|
||||
ARCHITECTURE RTL OF ahbMasterInterface IS
|
||||
|
||||
signal addressReg: unsigned(pAddress'range);
|
||||
signal newAddress: std_ulogic;
|
||||
signal writeReg: std_ulogic;
|
||||
|
||||
BEGIN
|
||||
------------------------------------------------------------------------------
|
||||
-- reset and clock
|
||||
hReset_n <= not reset;
|
||||
hClk <= clock;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- address and controls
|
||||
newAddress <= pReadStrobe or pWriteStrobe;
|
||||
|
||||
storeAddress: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
addressReg <= (others => '0');
|
||||
elsif rising_edge(clock) then
|
||||
if newAddress = '1' then
|
||||
addressReg <= pAddress;
|
||||
end if;
|
||||
end if;
|
||||
end process storeAddress;
|
||||
|
||||
hAddr <= pAddress when newAddress = '1'
|
||||
else addressReg;
|
||||
|
||||
storeWrite: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
writeReg <= '0';
|
||||
elsif rising_edge(clock) then
|
||||
if newAddress = '1' then
|
||||
writeReg <= pWriteStrobe;
|
||||
end if;
|
||||
end if;
|
||||
end process storeWrite;
|
||||
|
||||
hWrite <= pWriteStrobe when newAddress = '1'
|
||||
else writeReg;
|
||||
|
||||
hTrans <= transNonSeq when newAddress = '1'
|
||||
else transIdle;
|
||||
|
||||
hSize <= size16;
|
||||
hBurst <= burstSingle;
|
||||
hProt <= protDefault;
|
||||
hMastLock <= '0';
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- data out
|
||||
delayData: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
hWData <= (others => '0');
|
||||
elsif rising_edge(clock) then
|
||||
if pWriteStrobe = '1' then
|
||||
hWData <= pDataOut;
|
||||
end if;
|
||||
end if;
|
||||
end process delayData;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- data in
|
||||
pDataIn <= hRData;
|
||||
|
||||
END ARCHITECTURE RTL;
|
18
Libs/AhbLite/hdl/ahbMultiplexor_RTL.vhd
Normal file
18
Libs/AhbLite/hdl/ahbMultiplexor_RTL.vhd
Normal file
@ -0,0 +1,18 @@
|
||||
ARCHITECTURE RTL OF ahbMultiplexor IS
|
||||
BEGIN
|
||||
|
||||
multiplexData: process(hSel, hRDataV, hReadyV, hRespV)
|
||||
begin
|
||||
hRData <= (others => '0');
|
||||
hReady <= '1';
|
||||
hResp <= '0';
|
||||
for index in hSel'range loop
|
||||
if hSel(index) = '1' then
|
||||
hRData <= std_ulogic_vector(hRDataV(index));
|
||||
hReady <= hReadyV(index);
|
||||
hResp <= hRespV(index);
|
||||
end if;
|
||||
end loop;
|
||||
end process multiplexData;
|
||||
|
||||
END ARCHITECTURE RTL;
|
14
Libs/AhbLite/hdl/ahbMuxConnector_RTL.vhd
Normal file
14
Libs/AhbLite/hdl/ahbMuxConnector_RTL.vhd
Normal file
@ -0,0 +1,14 @@
|
||||
ARCHITECTURE RTL OF ahbMuxConnector IS
|
||||
BEGIN
|
||||
|
||||
hSel <= hSelV(index);
|
||||
|
||||
hRDataV(index) <= std_logic_vector(hRData);
|
||||
hReadyV(index) <= hReady;
|
||||
hRespV(index) <= hResp;
|
||||
|
||||
hRDataV <= (others => (others => 'Z'));
|
||||
hReadyV <= (others => 'Z');
|
||||
hRespV <= (others => 'Z');
|
||||
|
||||
END ARCHITECTURE RTL;
|
1
Libs/AhbLite/hds/.hdlsidedata/_ahbDecoder_RTL.vhd._fpf
Normal file
1
Libs/AhbLite/hds/.hdlsidedata/_ahbDecoder_RTL.vhd._fpf
Normal file
@ -0,0 +1 @@
|
||||
DIALECT atom VHDL_2008
|
4
Libs/AhbLite/hds/.hdlsidedata/_ahbLite_pkg.vhd._fpf
Normal file
4
Libs/AhbLite/hds/.hdlsidedata/_ahbLite_pkg.vhd._fpf
Normal file
@ -0,0 +1,4 @@
|
||||
INCLUDE list {
|
||||
DEFAULT atom 1
|
||||
}
|
||||
DIALECT atom VHDL_2002
|
4
Libs/AhbLite/hds/.hdlsidedata/_ahbLite_pkg_body.vhd._fpf
Normal file
4
Libs/AhbLite/hds/.hdlsidedata/_ahbLite_pkg_body.vhd._fpf
Normal file
@ -0,0 +1,4 @@
|
||||
INCLUDE list {
|
||||
DEFAULT atom 1
|
||||
}
|
||||
DIALECT atom VHDL_2002
|
@ -0,0 +1,4 @@
|
||||
INCLUDE list {
|
||||
DEFAULT atom 1
|
||||
}
|
||||
DIALECT atom VHDL_2008
|
@ -0,0 +1 @@
|
||||
DIALECT atom VHDL_2008
|
@ -0,0 +1 @@
|
||||
DIALECT atom VHDL_2008
|
@ -0,0 +1 @@
|
||||
DIALECT atom VHDL_2008
|
@ -0,0 +1 @@
|
||||
DIALECT atom VHDL_2008
|
@ -0,0 +1 @@
|
||||
DIALECT atom VHDL_2008
|
@ -0,0 +1 @@
|
||||
DIALECT atom VHDL_2008
|
2
Libs/AhbLite/hds/_ahbdecoder._epf
Normal file
2
Libs/AhbLite/hds/_ahbdecoder._epf
Normal file
@ -0,0 +1,2 @@
|
||||
DEFAULT_FILE atom ahbDecoder_RTL.vhd
|
||||
DEFAULT_ARCHITECTURE atom RTL
|
2
Libs/AhbLite/hds/_ahbmasterinterface._epf
Normal file
2
Libs/AhbLite/hds/_ahbmasterinterface._epf
Normal file
@ -0,0 +1,2 @@
|
||||
DEFAULT_ARCHITECTURE atom RTL
|
||||
DEFAULT_FILE atom ahbMasterInterface_RTL.vhd
|
2
Libs/AhbLite/hds/_ahbmultiplexor._epf
Normal file
2
Libs/AhbLite/hds/_ahbmultiplexor._epf
Normal file
@ -0,0 +1,2 @@
|
||||
DEFAULT_FILE atom ahbMultiplexor_RTL.vhd
|
||||
DEFAULT_ARCHITECTURE atom RTL
|
2
Libs/AhbLite/hds/_ahbmuxconnector._epf
Normal file
2
Libs/AhbLite/hds/_ahbmuxconnector._epf
Normal file
@ -0,0 +1,2 @@
|
||||
DEFAULT_FILE atom ahbMuxConnector_RTL.vhd
|
||||
DEFAULT_ARCHITECTURE atom RTL
|
1448
Libs/AhbLite/hds/ahb@decoder/symbol.sb
Normal file
1448
Libs/AhbLite/hds/ahb@decoder/symbol.sb
Normal file
File diff suppressed because it is too large
Load Diff
2594
Libs/AhbLite/hds/ahb@master@interface/symbol.sb
Normal file
2594
Libs/AhbLite/hds/ahb@master@interface/symbol.sb
Normal file
File diff suppressed because it is too large
Load Diff
1750
Libs/AhbLite/hds/ahb@multiplexor/symbol.sb
Normal file
1750
Libs/AhbLite/hds/ahb@multiplexor/symbol.sb
Normal file
File diff suppressed because it is too large
Load Diff
1835
Libs/AhbLite/hds/ahb@mux@connector/symbol.sb
Normal file
1835
Libs/AhbLite/hds/ahb@mux@connector/symbol.sb
Normal file
File diff suppressed because it is too large
Load Diff
BIN
Libs/AhbLite_test/doc/AMBA_AHB-Lite_spec.pdf
Normal file
BIN
Libs/AhbLite_test/doc/AMBA_AHB-Lite_spec.pdf
Normal file
Binary file not shown.
145
Libs/AhbLite_test/hdl/ahbLite_tester_test.vhd
Normal file
145
Libs/AhbLite_test/hdl/ahbLite_tester_test.vhd
Normal file
@ -0,0 +1,145 @@
|
||||
ARCHITECTURE test OF ahbLite_tester IS
|
||||
-- reset and clock
|
||||
constant clockPeriod: time := (1.0/clockFrequency) * 1 sec;
|
||||
signal clock_int: std_uLogic := '1';
|
||||
-- register access
|
||||
signal registerAddress: natural;
|
||||
signal registerData: integer;
|
||||
signal registerWrite: std_uLogic;
|
||||
signal registerRead: std_uLogic;
|
||||
-- AHB lite registers
|
||||
signal addressReg: unsigned(hAddr'range);
|
||||
signal writeReg: std_uLogic;
|
||||
signal selPeriph1Reg: std_uLogic;
|
||||
signal selPeriph2Reg: std_uLogic;
|
||||
signal hSel: std_uLogic;
|
||||
constant registerNb: positive := 2*periph2BaseAddress;
|
||||
subtype registerType is std_uLogic_vector(hWdata'range);
|
||||
type registerArrayType is array (registerNb-1 downto 0) of registerType;
|
||||
signal registerArray: registerArrayType;
|
||||
|
||||
BEGIN
|
||||
------------------------------------------------------------------------------
|
||||
-- reset and clock
|
||||
reset <= '1', '0' after 4*clockPeriod;
|
||||
|
||||
clock_int <= not clock_int after clockPeriod/2;
|
||||
clock <= transport clock_int after clockPeriod*9.0/10.0;
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- test sequence
|
||||
testSequence: process
|
||||
begin
|
||||
registerAddress <= 0;
|
||||
registerData <= 0;
|
||||
registerWrite <= '0';
|
||||
registerRead <= '0';
|
||||
wait for 100 ns;
|
||||
-- write periph1 register 0
|
||||
registerAddress <= 0;
|
||||
registerData <= 1;
|
||||
registerWrite <= '1', '0' after clockPeriod;
|
||||
wait for 8*clockPeriod;
|
||||
-- write periph1 register 1
|
||||
registerAddress <= 1;
|
||||
registerData <= 2;
|
||||
registerWrite <= '1', '0' after clockPeriod;
|
||||
wait for 8*clockPeriod;
|
||||
-- write periph2 register 0
|
||||
registerAddress <= periph2BaseAddress;
|
||||
registerData <= periph2BaseAddress + 1;
|
||||
registerWrite <= '1', '0' after clockPeriod;
|
||||
wait for 2*clockPeriod;
|
||||
-- write periph2 register 1
|
||||
registerAddress <= periph2BaseAddress + 1;
|
||||
registerData <= periph2BaseAddress + 2;
|
||||
registerWrite <= '1', '0' after clockPeriod;
|
||||
wait for 8*clockPeriod;
|
||||
-- read periph1 register 0
|
||||
registerAddress <= 0;
|
||||
registerRead <= '1', '0' after clockPeriod;
|
||||
wait for 8*clockPeriod;
|
||||
-- read periph2 register 0
|
||||
registerAddress <= periph2BaseAddress;
|
||||
registerRead <= '1', '0' after clockPeriod;
|
||||
wait for 8*clockPeriod;
|
||||
|
||||
wait;
|
||||
end process testSequence;
|
||||
|
||||
--============================================================================
|
||||
-- microprocessor bus access
|
||||
busAccess: process
|
||||
variable writeAccess: boolean;
|
||||
begin
|
||||
upAddress <= (others => '-');
|
||||
upDataOut <= (others => '-');
|
||||
upReadStrobe <= '0';
|
||||
upWriteStrobe <= '0';
|
||||
-- wait for transaction
|
||||
wait on registerWrite, registerRead;
|
||||
if not(hReset_n) = '0' then
|
||||
writeAccess := false;
|
||||
if rising_edge(registerWrite) then
|
||||
writeAccess := true;
|
||||
end if;
|
||||
-- single-cycle bus access
|
||||
wait until rising_edge(clock_int);
|
||||
upAddress <= to_unsigned(registerAddress, hAddr'length);
|
||||
if writeAccess then
|
||||
upWriteStrobe <= '1';
|
||||
upDataOut <= std_uLogic_vector(to_signed(registerData, upDataOut'length));
|
||||
else
|
||||
upReadStrobe <= '1';
|
||||
end if;
|
||||
wait until rising_edge(clock_int);
|
||||
end if;
|
||||
end process;
|
||||
|
||||
--============================================================================
|
||||
-- AHB bus access
|
||||
hSel <= hSelPeriph1 or hSelPeriph2;
|
||||
-- address and controls
|
||||
storeControls: process(hReset_n, hClk)
|
||||
begin
|
||||
if not(hReset_n) = '1' then
|
||||
addressReg <= (others => '0');
|
||||
writeReg <= '0';
|
||||
selPeriph1Reg <= '0';
|
||||
selPeriph2Reg <= '0';
|
||||
elsif rising_edge(hClk) then
|
||||
writeReg <= '0';
|
||||
if (hSel = '1') and (hTrans = transNonSeq) then
|
||||
addressReg <= hAddr;
|
||||
writeReg <= hWrite;
|
||||
selPeriph1Reg <= hSelPeriph1;
|
||||
selPeriph2Reg <= hSelPeriph2;
|
||||
end if;
|
||||
end if;
|
||||
end process storeControls;
|
||||
-- write registers
|
||||
storeRegisters: process(hReset_n, hClk)
|
||||
begin
|
||||
if not(hReset_n) = '1' then
|
||||
registerArray <= (others => (others => '0'));
|
||||
elsif rising_edge(hClk) then
|
||||
if writeReg = '1' then
|
||||
registerArray(to_integer(addressReg)) <= hWData;
|
||||
end if;
|
||||
end if;
|
||||
end process storeRegisters;
|
||||
-- read egisters
|
||||
hRDataPeriph1 <= registerArray(to_integer(addressReg))
|
||||
when addressReg < periph2BaseAddress
|
||||
else (others => '-');
|
||||
hReadyPeriph1 <= '1'; -- no wait state
|
||||
hRespPeriph1 <= '0'; -- data OK
|
||||
|
||||
hRDataPeriph2 <= registerArray(to_integer(addressReg))
|
||||
when addressReg >= periph2BaseAddress
|
||||
else (others => '-');
|
||||
hReadyPeriph2 <= '1'; -- no wait state
|
||||
hRespPeriph2 <= '0'; -- data OK
|
||||
|
||||
END ARCHITECTURE test;
|
@ -0,0 +1,4 @@
|
||||
INCLUDE list {
|
||||
DEFAULT atom 1
|
||||
}
|
||||
DIALECT atom VHDL_2008
|
3
Libs/AhbLite_test/hds/_ahblite_tb._epf
Normal file
3
Libs/AhbLite_test/hds/_ahblite_tb._epf
Normal file
@ -0,0 +1,3 @@
|
||||
DEFAULT_FILE atom ahb@lite_tb/struct.bd
|
||||
DEFAULT_ARCHITECTURE atom struct
|
||||
TOP_MARKER atom 1
|
2
Libs/AhbLite_test/hds/_ahblite_tester._epf
Normal file
2
Libs/AhbLite_test/hds/_ahblite_tester._epf
Normal file
@ -0,0 +1,2 @@
|
||||
DEFAULT_ARCHITECTURE atom test
|
||||
DEFAULT_FILE atom ahbLite_tester_test.vhd
|
7355
Libs/AhbLite_test/hds/ahb@lite_tb/struct.bd
Normal file
7355
Libs/AhbLite_test/hds/ahb@lite_tb/struct.bd
Normal file
File diff suppressed because it is too large
Load Diff
1258
Libs/AhbLite_test/hds/ahb@lite_tb/symbol.sb
Normal file
1258
Libs/AhbLite_test/hds/ahb@lite_tb/symbol.sb
Normal file
File diff suppressed because it is too large
Load Diff
2685
Libs/AhbLite_test/hds/ahb@lite_tester/interface
Normal file
2685
Libs/AhbLite_test/hds/ahb@lite_tester/interface
Normal file
File diff suppressed because it is too large
Load Diff
2
Libs/AhbLite_test/hds/hds/_cordic_tb._epf
Normal file
2
Libs/AhbLite_test/hds/hds/_cordic_tb._epf
Normal file
@ -0,0 +1,2 @@
|
||||
DEFAULT_ARCHITECTURE atom struct
|
||||
DEFAULT_FILE atom cordic_tb/struct.bd
|
2
Libs/AhbLite_test/hds/hds/_cordic_tester._epf
Normal file
2
Libs/AhbLite_test/hds/hds/_cordic_tester._epf
Normal file
@ -0,0 +1,2 @@
|
||||
DEFAULT_FILE atom cordic_tester_test.vhd
|
||||
DEFAULT_ARCHITECTURE atom test
|
3
Libs/AhbLite_test/hds/hds/_motherboard_tb._epf
Normal file
3
Libs/AhbLite_test/hds/hds/_motherboard_tb._epf
Normal file
@ -0,0 +1,3 @@
|
||||
DEFAULT_ARCHITECTURE atom struct
|
||||
DEFAULT_FILE atom motherboard_tb/struct.bd
|
||||
TOP_MARKER atom 1
|
2
Libs/AhbLite_test/hds/hds/_motherboard_tester._epf
Normal file
2
Libs/AhbLite_test/hds/hds/_motherboard_tester._epf
Normal file
@ -0,0 +1,2 @@
|
||||
DEFAULT_FILE atom motherboard_tester_test.vhd
|
||||
DEFAULT_ARCHITECTURE atom test
|
89
Libs/Common/hdl/blinker_arch.vhd
Normal file
89
Libs/Common/hdl/blinker_arch.vhd
Normal file
@ -0,0 +1,89 @@
|
||||
-- filename: blinker.vhd
|
||||
-- kind: vhdl file
|
||||
-- first created: 18.06.2012
|
||||
-- created by: zas
|
||||
--------------------------------------------------------------------------------
|
||||
-- History:
|
||||
-- v0.1 : zas 18.06.2012 -- Initial Version
|
||||
--------------------------------------------------------------------------------
|
||||
-- Description:
|
||||
-- For let blinking a LED with an signal event
|
||||
-- Mode = 0 (reactive on rising edge)
|
||||
-- ___________________________________________
|
||||
-- input ____/
|
||||
-- ___________________
|
||||
-- output ____/ \_______________________
|
||||
-- time 0s 0.5s 1s
|
||||
--
|
||||
-- _
|
||||
-- input ____/ \_________________________________________
|
||||
-- ___________________
|
||||
-- output ____/ \_______________________
|
||||
-- time 0s 0.5s 1s
|
||||
----
|
||||
-- Mode = 1 (reactive on falling edge)
|
||||
-- _____
|
||||
-- input \__________________________________________
|
||||
-- ___________________
|
||||
-- output ______/ \_____________________
|
||||
-- time 0s 0.5s 1s
|
||||
--
|
||||
-- _
|
||||
-- input ____/ \_________________________________________
|
||||
-- ___________________
|
||||
-- output ______ / \____________________
|
||||
-- time 0s 0.5s 1s
|
||||
--
|
||||
--------------------------------------------------------------------------------
|
||||
LIBRARY ieee;
|
||||
USE ieee.std_logic_1164.all;
|
||||
USE ieee.NUMERIC_STD.all;
|
||||
|
||||
LIBRARY Common;
|
||||
USE Common.CommonLib.all;
|
||||
|
||||
|
||||
ARCHITECTURE arch OF blinker IS
|
||||
|
||||
constant c : integer := clockFrequency/2; -- 500ms blink
|
||||
|
||||
signal cnt : unsigned(requiredBitNb(c)-1 downto 0);
|
||||
signal en_delay : std_ulogic;
|
||||
signal blink_int : std_ulogic;
|
||||
|
||||
BEGIN
|
||||
|
||||
process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
en_delay <= '0';
|
||||
blink_int <= '0';
|
||||
cnt <= (others => '0');
|
||||
elsif rising_edge(clock) then
|
||||
en_delay <= en;
|
||||
-- detect rising_edge
|
||||
if mode = 0 then
|
||||
if blink_int = '0' and en_delay = '0' and en = '1' then
|
||||
blink_int <= '1';
|
||||
end if;
|
||||
else
|
||||
-- detect falling edge
|
||||
if blink_int = '0' and en_delay = '1' and en = '0' then
|
||||
blink_int <= '1';
|
||||
end if;
|
||||
end if;
|
||||
-- blink
|
||||
if blink_int = '1' then
|
||||
if (cnt < c) then
|
||||
cnt <= cnt + 1;
|
||||
else
|
||||
cnt <= (others => '0');
|
||||
blink_int <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Set output
|
||||
blink <= blink_int;
|
||||
END ARCHITECTURE arch;
|
68
Libs/Common/hdl/commonLib.vhd
Normal file
68
Libs/Common/hdl/commonLib.vhd
Normal file
@ -0,0 +1,68 @@
|
||||
--------------------------------------------------------------------------------
|
||||
-- Copyright 2012 HES-SO Valais Wallis (www.hevs.ch)
|
||||
--------------------------------------------------------------------------------
|
||||
-- This program is free software: you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 3 of the License, or
|
||||
-- (at your option) any later version.
|
||||
--
|
||||
-- This program IS distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
-- You should have received a copy of the GNU General Public License along with
|
||||
-- this program. If not, see <http://www.gnu.org/licenses/>
|
||||
-- -----------------------------------------------------------------------------
|
||||
-- Common Lib
|
||||
--
|
||||
-- -----------------------------------------------------------------------------
|
||||
-- Authors:
|
||||
-- cof: [François Corthay](francois.corthay@hevs.ch)
|
||||
-- guo: [Oliver A. Gubler](oliver.gubler@hevs.ch)
|
||||
-- -----------------------------------------------------------------------------
|
||||
-- Changelog:
|
||||
-- 2016-06 : guo
|
||||
-- added function sel
|
||||
-- 2015-06 : guo
|
||||
-- added counterBitNb
|
||||
-- added documentation
|
||||
-- -----------------------------------------------------------------------------
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
use IEEE.numeric_std.all;
|
||||
|
||||
PACKAGE CommonLib IS
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- Returns the number of bits needed to represent the given val
|
||||
-- Examples:
|
||||
-- requiredBitNb(1) = 1 (1)
|
||||
-- requiredBitNb(2) = 2 (10)
|
||||
-- requiredBitNb(3) = 2 (11)
|
||||
function requiredBitNb(val : integer) return integer;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- Returns the number of bits needed to count val times (0 to val-1)
|
||||
-- Examples:
|
||||
-- counterBitNb(1) = 1 (0)
|
||||
-- counterBitNb(2) = 1 (0->1)
|
||||
-- counterBitNb(3) = 2 (0->1->10)
|
||||
function counterBitNb(val : integer) return integer;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- Functions to return one or the other input based on a boolean.
|
||||
-- Can be used to build conditional constants.
|
||||
-- Example:
|
||||
-- constant bonjour_c : string := sel(ptpRole = master, "fpga20", "fpga02");
|
||||
function sel(Cond : BOOLEAN; If_True, If_False : integer)
|
||||
return integer;
|
||||
function sel(Cond : BOOLEAN; If_True, If_False : string)
|
||||
return string;
|
||||
function sel(Cond : BOOLEAN; If_True, If_False : std_ulogic_vector)
|
||||
return std_ulogic_vector;
|
||||
function sel(Cond : BOOLEAN; If_True, If_False : unsigned)
|
||||
return unsigned;
|
||||
function sel(Cond : BOOLEAN; If_True, If_False : signed)
|
||||
return signed;
|
||||
|
||||
END CommonLib;
|
105
Libs/Common/hdl/commonLib_body.vhd
Normal file
105
Libs/Common/hdl/commonLib_body.vhd
Normal file
@ -0,0 +1,105 @@
|
||||
--------------------------------------------------------------------------------
|
||||
-- Copyright 2012 HES-SO Valais Wallis (www.hevs.ch)
|
||||
--------------------------------------------------------------------------------
|
||||
-- This program is free software: you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 3 of the License, or
|
||||
-- (at your option) any later version.
|
||||
--
|
||||
-- This program IS distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
-- You should have received a copy of the GNU General Public License along with
|
||||
-- this program. If not, see <http://www.gnu.org/licenses/>
|
||||
-- -----------------------------------------------------------------------------
|
||||
-- Often used functions
|
||||
--
|
||||
-- -----------------------------------------------------------------------------
|
||||
-- Authors:
|
||||
-- cof: [François Corthay](francois.corthay@hevs.ch)
|
||||
-- guo: [Oliver A. Gubler](oliver.gubler@hevs.ch)
|
||||
-- -----------------------------------------------------------------------------
|
||||
-- Changelog:
|
||||
-- 2016-06 : guo
|
||||
-- added function sel
|
||||
-- 2015-06 : guo
|
||||
-- added counterBitNb
|
||||
-- -----------------------------------------------------------------------------
|
||||
PACKAGE BODY CommonLib IS
|
||||
|
||||
function requiredBitNb (val : integer) return integer is
|
||||
variable powerOfTwo, bitNb : integer;
|
||||
begin
|
||||
powerOfTwo := 1;
|
||||
bitNb := 0;
|
||||
while powerOfTwo <= val loop
|
||||
powerOfTwo := 2 * powerOfTwo;
|
||||
bitNb := bitNb + 1;
|
||||
end loop;
|
||||
return bitNb;
|
||||
end requiredBitNb;
|
||||
|
||||
function counterBitNb (val : integer) return integer is
|
||||
variable powerOfTwo, bitNb : integer;
|
||||
begin
|
||||
powerOfTwo := 1;
|
||||
bitNb := 0;
|
||||
while powerOfTwo < val loop
|
||||
powerOfTwo := 2 * powerOfTwo;
|
||||
bitNb := bitNb + 1;
|
||||
end loop;
|
||||
return bitNb;
|
||||
end counterBitNb;
|
||||
|
||||
function sel(Cond : BOOLEAN; If_True, If_False : integer)
|
||||
return integer is
|
||||
begin
|
||||
if (Cond = TRUE) then
|
||||
return (If_True);
|
||||
else
|
||||
return (If_False);
|
||||
end if;
|
||||
end function sel;
|
||||
|
||||
function sel(Cond : BOOLEAN; If_True, If_False : string)
|
||||
return string is
|
||||
begin
|
||||
if (Cond = TRUE) then
|
||||
return (If_True);
|
||||
else
|
||||
return (If_False);
|
||||
end if;
|
||||
end function sel;
|
||||
|
||||
function sel(Cond : BOOLEAN; If_True, If_False : std_ulogic_vector)
|
||||
return std_ulogic_vector is
|
||||
begin
|
||||
if (Cond = TRUE) then
|
||||
return (If_True);
|
||||
else
|
||||
return (If_False);
|
||||
end if;
|
||||
end function sel;
|
||||
|
||||
function sel(Cond : BOOLEAN; If_True, If_False : unsigned)
|
||||
return unsigned is
|
||||
begin
|
||||
if (Cond = TRUE) then
|
||||
return (If_True);
|
||||
else
|
||||
return (If_False);
|
||||
end if;
|
||||
end function sel;
|
||||
|
||||
function sel(Cond : BOOLEAN; If_True, If_False : signed)
|
||||
return signed is
|
||||
begin
|
||||
if (Cond = TRUE) then
|
||||
return (If_True);
|
||||
else
|
||||
return (If_False);
|
||||
end if;
|
||||
end function sel;
|
||||
|
||||
END CommonLib;
|
112
Libs/Common/hdl/debounce_rtl.vhd
Normal file
112
Libs/Common/hdl/debounce_rtl.vhd
Normal file
@ -0,0 +1,112 @@
|
||||
-- filename: debounced.vhd
|
||||
-- kind: vhdl file
|
||||
-- first created: 11.01.2024
|
||||
-- created by: boy
|
||||
--------------------------------------------------------------------------------
|
||||
-- History:
|
||||
-- v0.1 : boy 11.01.2024 -- Initial Version
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Description:
|
||||
-- debounceds a button on both edges.
|
||||
-- _ _ ____________________ _ _
|
||||
-- input ____/ \_/ \_/ \_/ \_/ \______
|
||||
-- _____________________________
|
||||
-- output __________________/ \____________
|
||||
--
|
||||
--------------------------------------------------------------------------------
|
||||
-- Generics:
|
||||
-- g_debounceTime (time) : parameter to fix the debounce time.
|
||||
-- g_minConsecutiveStateCount (integer) : The number of consecutive readings of the same state required to change the output.
|
||||
-- g_clockFrequency (real) : Clock frequency of the system
|
||||
-- g_activeState (std_ulogic) : The output will be reset in "inactive" state.
|
||||
--------------------------------------------------------------------------------
|
||||
-- Input is read each g_debounceTime, and a constant value must appear for
|
||||
-- g_minConsecutiveStateCount to be forwarded on the output.
|
||||
-- To update the output, x consecutive samples needs to have
|
||||
-- the exact same value. x is given with the "g_minConsecutiveStateCount" parameter
|
||||
--------------------------------------------------------------------------------
|
||||
LIBRARY ieee;
|
||||
USE ieee.math_real.all;
|
||||
LIBRARY Common;
|
||||
USE Common.CommonLib.all;
|
||||
|
||||
|
||||
ARCHITECTURE rtl OF debounce IS
|
||||
|
||||
-- Creates a vector of alternating 1's and 0's (0b...1010)
|
||||
pure function alternating_ones_and_zeros(length : integer) return std_ulogic_vector is
|
||||
variable ret_val : std_ulogic_vector(length - 1 downto 0);
|
||||
BEGIN
|
||||
for i in 0 to length - 1 loop
|
||||
if i mod 2 = 1 then
|
||||
ret_val(i) := '1';
|
||||
else
|
||||
ret_val(i) := '0';
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
return ret_val;
|
||||
end function alternating_ones_and_zeros;
|
||||
|
||||
-- To check if all bits are '1'
|
||||
constant c_LOGICAL_HIGH_VALID: std_ulogic_vector((g_minConsecutiveStateCount-1) downto 0) := (others=>'1');
|
||||
-- To check if all bits are '0'
|
||||
constant c_LOGICAL_LOW_VALID: std_ulogic_vector((g_minConsecutiveStateCount-1) downto 0) := (others=>'0');
|
||||
-- Alternating 1's and 0's for reset value
|
||||
constant c_INIT_SAMPLE: std_ulogic_vector((g_minConsecutiveStateCount-1) downto 0) := alternating_ones_and_zeros(g_minConsecutiveStateCount);
|
||||
-- Delay between two samplings
|
||||
-- delay = (g_debounceTime * g_clockFrequency) / g_minConsecutiveStateCount - 1
|
||||
constant DELAY: positive := integer(ceil(((real(g_debounceTime / 1 ps) / 1.0e12) * g_clockFrequency) / real(g_minConsecutiveStateCount))) - 1;
|
||||
|
||||
-- Holds the state of registered consecutive inputs
|
||||
signal lvec_sample: std_ulogic_vector((g_minConsecutiveStateCount-1) downto 0);
|
||||
-- Defines when we will sample (based on given DELAY)
|
||||
signal lsig_samplePulse: std_ulogic := '0';
|
||||
-- Counter for the delay
|
||||
signal lvec_count : unsigned(requiredBitNb(DELAY)-1 downto 0);
|
||||
|
||||
BEGIN
|
||||
|
||||
clockDivider: process(reset, clock) --Clock Divider
|
||||
begin
|
||||
if reset = '1' then
|
||||
lvec_count <= (others => '0');
|
||||
lsig_samplePulse <= '0';
|
||||
elsif rising_edge(clock) then
|
||||
if (lvec_count < DELAY) then
|
||||
lvec_count <= lvec_count + 1;
|
||||
lsig_samplePulse <= '0';
|
||||
else
|
||||
lvec_count <= (others => '0');
|
||||
lsig_samplePulse <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end process clockDivider;
|
||||
|
||||
sampling: process(reset, clock) --Sampling Process
|
||||
begin
|
||||
if reset = '1' then
|
||||
lvec_sample <= c_INIT_SAMPLE;
|
||||
elsif rising_edge(clock) then
|
||||
if lsig_samplePulse = '1' then
|
||||
lvec_sample((g_minConsecutiveStateCount - 1) downto 1) <= lvec_sample((g_minConsecutiveStateCount - 2) downto 0); -- Left Shift
|
||||
lvec_sample(0) <= input;
|
||||
end if;
|
||||
end if;
|
||||
end process sampling;
|
||||
|
||||
inputDebouncing: process(reset, clock) --Input Debouncing
|
||||
begin
|
||||
if reset = '1' then
|
||||
debounced <= not g_activeState;
|
||||
elsif rising_edge(clock) then
|
||||
if lvec_sample = c_LOGICAL_HIGH_VALID then --Active High Constant Out
|
||||
debounced <= '1';
|
||||
elsif lvec_sample = c_LOGICAL_LOW_VALID then
|
||||
debounced <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process inputDebouncing;
|
||||
END ARCHITECTURE rtl;
|
||||
|
97
Libs/Common/hdl/debouncerULogicVector_RTL.vhd
Normal file
97
Libs/Common/hdl/debouncerULogicVector_RTL.vhd
Normal file
@ -0,0 +1,97 @@
|
||||
-- filename: debouncer.vhd
|
||||
-- kind: vhdl file
|
||||
-- first created: 05.03.2012
|
||||
-- created by: zas
|
||||
--------------------------------------------------------------------------------
|
||||
-- History:
|
||||
-- v0.1 : zas 05.03.2012 -- Initial Version
|
||||
-- v0.2 : cof 22.01.2013 -- synchronization to clock
|
||||
--------------------------------------------------------------------------------
|
||||
-- Description:
|
||||
-- Debounces a button on both edges.
|
||||
-- _ _ ____________________ _ _
|
||||
-- input ____/ \_/ \_/ \_/ \_/ \______
|
||||
-- _____________________________
|
||||
-- output _____/ \____________
|
||||
--
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
ARCHITECTURE rtl OF debouncerULogicVector IS
|
||||
|
||||
signal inputNormal : std_ulogic_vector(input'range);
|
||||
signal inputSynch, inputDelayed, inputChanged : std_ulogic;
|
||||
signal debounceCounter : unsigned(counterBitNb-1 downto 0);
|
||||
|
||||
BEGIN
|
||||
------------------------------------------------------------------------------
|
||||
-- adapt polarity
|
||||
adaptPolarity: process(input)
|
||||
begin
|
||||
for index in input'range loop
|
||||
inputNormal(index) <= input(index) xor invertInput;
|
||||
end loop;
|
||||
end process adaptPolarity;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- Synchronize input to clock
|
||||
synchInput: process(reset, clock)
|
||||
variable inputOr : std_ulogic;
|
||||
begin
|
||||
if reset = '1' then
|
||||
inputSynch <= '0';
|
||||
elsif rising_edge(clock) then
|
||||
inputOr := '0';
|
||||
for index in input'range loop
|
||||
inputOr := inputOr or inputNormal(index);
|
||||
end loop;
|
||||
inputSynch <= inputOr;
|
||||
end if;
|
||||
end process synchInput;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- Find edge on input
|
||||
delayInput: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
inputDelayed <= '0';
|
||||
elsif rising_edge(clock) then
|
||||
inputDelayed <= inputSynch;
|
||||
end if;
|
||||
end process delayInput;
|
||||
|
||||
inputChanged <= '1' when inputDelayed /= inputSynch
|
||||
else '0';
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- Debounce counter
|
||||
countDeadTime: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
debounceCounter <= (others => '0');
|
||||
elsif rising_edge(clock) then
|
||||
if debounceCounter = 0 then
|
||||
if inputChanged = '1' then
|
||||
debounceCounter <= debounceCounter - 1;
|
||||
end if;
|
||||
else
|
||||
debounceCounter <= debounceCounter - 1;
|
||||
end if;
|
||||
end if;
|
||||
end process countDeadTime;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- Update output
|
||||
updateOutput: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
debounced <= (others => '0');
|
||||
elsif rising_edge(clock) then
|
||||
if (inputChanged = '1') and (debounceCounter = 0) then
|
||||
debounced <= inputNormal;
|
||||
elsif debounceCounter = 1 then
|
||||
debounced <= inputNormal;
|
||||
end if;
|
||||
end if;
|
||||
end process updateOutput;
|
||||
|
||||
END ARCHITECTURE rtl;
|
83
Libs/Common/hdl/debouncer_RTL.vhd
Normal file
83
Libs/Common/hdl/debouncer_RTL.vhd
Normal file
@ -0,0 +1,83 @@
|
||||
-- filename: debouncer.vhd
|
||||
-- kind: vhdl file
|
||||
-- first created: 05.03.2012
|
||||
-- created by: zas
|
||||
--------------------------------------------------------------------------------
|
||||
-- History:
|
||||
-- v0.1 : zas 05.03.2012 -- Initial Version
|
||||
-- v0.2 : cof 22.01.2013 -- synchronization to clock
|
||||
-- -- direct reaction on both edges
|
||||
--------------------------------------------------------------------------------
|
||||
-- Description:
|
||||
-- Debounces a button on both edges.
|
||||
-- _ _ ____________________ _ _
|
||||
-- input ____/ \_/ \_/ \_/ \_/ \______
|
||||
-- _____________________________
|
||||
-- output _____/ \____________
|
||||
--
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
ARCHITECTURE rtl OF debouncer IS
|
||||
|
||||
signal debounceCounter : unsigned(counterBitNb-1 downto 0);
|
||||
signal inputSynch, inputDelayed, inputChanged : std_ulogic;
|
||||
|
||||
BEGIN
|
||||
------------------------------------------------------------------------------
|
||||
-- Synchronize input to clock
|
||||
synchInput: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
inputSynch <= '0';
|
||||
elsif rising_edge(clock) then
|
||||
inputSynch <= input xor invertInput;
|
||||
end if;
|
||||
end process synchInput;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- Find edge on input
|
||||
delayInput: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
inputDelayed <= '0';
|
||||
elsif rising_edge(clock) then
|
||||
inputDelayed <= inputSynch;
|
||||
end if;
|
||||
end process delayInput;
|
||||
|
||||
inputChanged <= '1' when inputDelayed /= inputSynch
|
||||
else '0';
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- Debounce counter
|
||||
countDeadTime: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
debounceCounter <= (others => '0');
|
||||
elsif rising_edge(clock) then
|
||||
if debounceCounter = 0 then
|
||||
if inputChanged = '1' then
|
||||
debounceCounter <= debounceCounter - 1;
|
||||
end if;
|
||||
else
|
||||
debounceCounter <= debounceCounter - 1;
|
||||
end if;
|
||||
end if;
|
||||
end process countDeadTime;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- Update output
|
||||
updateOutput: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
debounced <= '0';
|
||||
elsif rising_edge(clock) then
|
||||
if (inputChanged = '1') and (debounceCounter = 0) then
|
||||
debounced <= input;
|
||||
elsif debounceCounter = 1 then
|
||||
debounced <= input;
|
||||
end if;
|
||||
end if;
|
||||
end process updateOutput;
|
||||
|
||||
END ARCHITECTURE rtl;
|
48
Libs/Common/hdl/edgeDetector_rtl.vhd
Normal file
48
Libs/Common/hdl/edgeDetector_rtl.vhd
Normal file
@ -0,0 +1,48 @@
|
||||
--------------------------------------------------------------------------------
|
||||
-- Copyright 2014 HES-SO Valais Wallis (www.hevs.ch)
|
||||
--
|
||||
-- This program is free software: you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 3 of the License, or
|
||||
-- (at your option) any later version.
|
||||
--
|
||||
-- This program IS distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
-- You should have received a copy of the GNU General Public License along with
|
||||
-- this program. If not, see <http://www.gnu.org/licenses/>
|
||||
--------------------------------------------------------------------------------
|
||||
-- EdgeDetector
|
||||
-- Detect rising and falling edges of a signal.
|
||||
--
|
||||
--------------------------------------------------------------------------------
|
||||
-- History:
|
||||
-- v0.1 : guo 2014-04-02 -- Initial version
|
||||
-- v1.0 : cof 2019-10-02 -- Updated symbol
|
||||
--------------------------------------------------------------------------------
|
||||
ARCHITECTURE RTL OF edgeDetector IS
|
||||
|
||||
SIGNAL pulse_delayed : std_ulogic;
|
||||
SIGNAL rising_detected_s : std_ulogic;
|
||||
SIGNAL falling_detected_s : std_ulogic;
|
||||
|
||||
BEGIN
|
||||
|
||||
-- delay pulse
|
||||
reg : PROCESS (reset, clock)
|
||||
BEGIN
|
||||
IF reset = '1' THEN
|
||||
pulse_delayed <= '0';
|
||||
ELSIF rising_edge(clock) THEN
|
||||
pulse_delayed <= pulse;
|
||||
END IF;
|
||||
END PROCESS reg ;
|
||||
|
||||
-- edge detection
|
||||
rising <= '1' when (pulse = '1') and (pulse_delayed = '0')
|
||||
else '0';
|
||||
falling <= '1' when (pulse = '0') and (pulse_delayed = '1')
|
||||
else '0';
|
||||
|
||||
END ARCHITECTURE RTL;
|
76
Libs/Common/hdl/rotaryToUnsigned_rtl.vhd
Normal file
76
Libs/Common/hdl/rotaryToUnsigned_rtl.vhd
Normal file
@ -0,0 +1,76 @@
|
||||
ARCHITECTURE rtl OF rotaryToUnsigned IS
|
||||
|
||||
signal rotaryDelayed1, rotaryDelayed2, rotaryStable : unsigned(rotary'range);
|
||||
signal rotary_changed : std_ulogic;
|
||||
signal glitchDelayCounter : unsigned(counterBitNb-1 downto 0);
|
||||
signal rotaryStableDelayed : unsigned(rotary'range);
|
||||
signal numberMsbs : unsigned(number'length-rotary'length-1 downto 0);
|
||||
|
||||
BEGIN
|
||||
------------------------------------------------------------------------------
|
||||
-- synchronize input and detect changes
|
||||
delayRotary: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
rotaryDelayed1 <= (others => '0');
|
||||
rotaryDelayed2 <= (others => '0');
|
||||
elsif rising_edge(clock) then
|
||||
rotaryDelayed1 <= rotary;
|
||||
rotaryDelayed2 <= rotaryDelayed1;
|
||||
end if;
|
||||
end process delayRotary;
|
||||
|
||||
rotary_changed <= '1' when rotaryDelayed1 /= rotaryDelayed2
|
||||
else '0';
|
||||
-- count dead time
|
||||
countDeadTime: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
glitchDelayCounter <= (others => '1');
|
||||
elsif rising_edge(clock) then
|
||||
if rotary_changed = '1' then
|
||||
glitchDelayCounter <= (others => '1');
|
||||
elsif glitchDelayCounter > 0 then
|
||||
glitchDelayCounter <= glitchDelayCounter - 1;
|
||||
end if;
|
||||
end if;
|
||||
end process countDeadTime;
|
||||
-- store new rotary button value
|
||||
storeRotary: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
rotaryStable <= (others => '0');
|
||||
elsif rising_edge(clock) then
|
||||
if glitchDelayCounter = 0 then
|
||||
rotaryStable <= rotaryDelayed2;
|
||||
end if;
|
||||
end if;
|
||||
end process storeRotary;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- keep previous value of stablilzed rotary
|
||||
delayRotaryStable: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
rotaryStableDelayed <= (others => '0');
|
||||
elsif rising_edge(clock) then
|
||||
rotaryStableDelayed <= rotaryStable;
|
||||
end if;
|
||||
end process delayRotaryStable;
|
||||
-- synchronize input and detect changes
|
||||
updateMsbs: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
numberMsbs <= (others => '0');
|
||||
elsif rising_edge(clock) then
|
||||
if (rotaryStable = 0) and (rotaryStableDelayed+1 = 0) then
|
||||
numberMsbs <= numberMsbs + 1;
|
||||
elsif (rotaryStable+1 = 0) and (rotaryStableDelayed = 0) then
|
||||
numberMsbs <= numberMsbs - 1;
|
||||
end if;
|
||||
end if;
|
||||
end process updateMsbs;
|
||||
|
||||
number <= numberMsbs & rotaryStableDelayed;
|
||||
|
||||
END ARCHITECTURE rtl;
|
82
Libs/Common/hdl/spikeFilter_RTL.vhd
Normal file
82
Libs/Common/hdl/spikeFilter_RTL.vhd
Normal file
@ -0,0 +1,82 @@
|
||||
--------------------------------------------------------------------------------
|
||||
-- Description:
|
||||
-- Filters short time spikes.
|
||||
-- _ _ ____________________ _ _
|
||||
-- input ____/ \_/ \_/ \_/ \_/ \_________________
|
||||
-- _____________________________
|
||||
-- output ________________/ \____________
|
||||
--
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
ARCHITECTURE rtl OF spikeFilter IS
|
||||
|
||||
signal filterCounter : unsigned(counterBitNb-1 downto 0);
|
||||
signal inputSynch, inputDelayed, inputChanged : std_ulogic;
|
||||
|
||||
BEGIN
|
||||
------------------------------------------------------------------------------
|
||||
-- Synchronize input to clock
|
||||
synchInput: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
inputSynch <= '0';
|
||||
elsif rising_edge(clock) then
|
||||
inputSynch <= input xor invertInput;
|
||||
end if;
|
||||
end process synchInput;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- Find edge on input
|
||||
delayInput: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
inputDelayed <= '0';
|
||||
elsif rising_edge(clock) then
|
||||
inputDelayed <= inputSynch;
|
||||
end if;
|
||||
end process delayInput;
|
||||
|
||||
inputChanged <= '1' when inputDelayed /= inputSynch
|
||||
else '0';
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- Debounce counter
|
||||
countDeadTime: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
filterCounter <= (others => '0');
|
||||
elsif rising_edge(clock) then
|
||||
if filterCounter = 0 then
|
||||
if inputChanged = '1' then
|
||||
filterCounter <= filterCounter + 1;
|
||||
end if;
|
||||
elsif signed(filterCounter)+1 = 0 then
|
||||
if inputChanged = '1' then
|
||||
filterCounter <= filterCounter - 1;
|
||||
end if;
|
||||
else
|
||||
if inputSynch = '0' then
|
||||
filterCounter <= filterCounter - 1;
|
||||
else
|
||||
filterCounter <= filterCounter + 1;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process countDeadTime;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- Update output
|
||||
updateOutput: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
filtered <= '0';
|
||||
elsif rising_edge(clock) then
|
||||
if filterCounter = 0 then
|
||||
filtered <= '0';
|
||||
elsif signed(filterCounter)+1 = 0 then
|
||||
filtered <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end process updateOutput;
|
||||
|
||||
END ARCHITECTURE rtl;
|
90
Libs/Common/hdl/toggler_RTL.vhd
Normal file
90
Libs/Common/hdl/toggler_RTL.vhd
Normal file
@ -0,0 +1,90 @@
|
||||
-- filename: toggler.vhd
|
||||
-- kind: vhdl file
|
||||
-- first created: 05.03.2012
|
||||
-- created by: zas
|
||||
--------------------------------------------------------------------------------
|
||||
-- History:
|
||||
-- v0.1 : cof 22.01.2013 -- Initial version
|
||||
--------------------------------------------------------------------------------
|
||||
-- Description:
|
||||
-- Debounces a button on both edges.
|
||||
-- _ _
|
||||
-- input ____/ \__________________________/ \____________
|
||||
-- _____________________________
|
||||
-- output _____/ \____________
|
||||
--
|
||||
-- If the generic "counterBitNb" is greater than zero, a debouncer is placed on
|
||||
-- the input signal.
|
||||
--
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
ARCHITECTURE rtl OF toggler IS
|
||||
|
||||
signal inputDebounced : std_ulogic;
|
||||
signal inputDelayed, inputChangedTo1 : std_ulogic;
|
||||
signal toggle_int : std_ulogic;
|
||||
|
||||
COMPONENT debouncer
|
||||
GENERIC (
|
||||
counterBitNb : positive := 18;
|
||||
invertInput : std_ulogic := '0'
|
||||
);
|
||||
PORT (
|
||||
reset : IN std_ulogic ;
|
||||
clock : IN std_ulogic ;
|
||||
input : IN std_ulogic ;
|
||||
debounced : OUT std_ulogic
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
BEGIN
|
||||
------------------------------------------------------------------------------
|
||||
-- Debounce input
|
||||
useInputDirectly: if counterBitNb = 0 generate
|
||||
inputDebounced <= input;
|
||||
end generate useInputDirectly;
|
||||
|
||||
debounceInput: if counterBitNb > 0 generate
|
||||
I_debouncer : debouncer
|
||||
GENERIC MAP (
|
||||
counterBitNb => counterBitNb,
|
||||
invertInput => invertInput
|
||||
)
|
||||
PORT MAP (
|
||||
reset => reset,
|
||||
clock => clock,
|
||||
input => input,
|
||||
debounced => inputDebounced
|
||||
);
|
||||
end generate debounceInput;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- Find edge on input
|
||||
delayInput: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
inputDelayed <= '0';
|
||||
elsif rising_edge(clock) then
|
||||
inputDelayed <= inputDebounced;
|
||||
end if;
|
||||
end process delayInput;
|
||||
|
||||
inputChangedTo1 <= '1' when (inputDebounced = '1') and (inputDelayed = '0')
|
||||
else '0';
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- Toggle output
|
||||
toggleOutput: process(reset, clock)
|
||||
begin
|
||||
if reset = '1' then
|
||||
toggle_int <= '0';
|
||||
elsif rising_edge(clock) then
|
||||
if inputChangedTo1 = '1' then
|
||||
toggle_int <= not toggle_int;
|
||||
end if;
|
||||
end if;
|
||||
end process toggleOutput;
|
||||
|
||||
toggle <= toggle_int;
|
||||
|
||||
END ARCHITECTURE rtl;
|
4
Libs/Common/hds/.hdlsidedata/_blinker_arch.vhd._fpf
Normal file
4
Libs/Common/hds/.hdlsidedata/_blinker_arch.vhd._fpf
Normal file
@ -0,0 +1,4 @@
|
||||
INCLUDE list {
|
||||
DEFAULT atom 1
|
||||
}
|
||||
DIALECT atom VHDL_2008
|
1
Libs/Common/hds/.hdlsidedata/_blinker_entity.vhg._fpf
Normal file
1
Libs/Common/hds/.hdlsidedata/_blinker_entity.vhg._fpf
Normal file
@ -0,0 +1 @@
|
||||
DIALECT atom VHDL_2008
|
1
Libs/Common/hds/.hdlsidedata/_commonLib.vhd._fpf
Normal file
1
Libs/Common/hds/.hdlsidedata/_commonLib.vhd._fpf
Normal file
@ -0,0 +1 @@
|
||||
DIALECT atom VHDL_87
|
1
Libs/Common/hds/.hdlsidedata/_commonLib_body.vhd._fpf
Normal file
1
Libs/Common/hds/.hdlsidedata/_commonLib_body.vhd._fpf
Normal file
@ -0,0 +1 @@
|
||||
DIALECT atom VHDL_87
|
4
Libs/Common/hds/.hdlsidedata/_debounce_rtl.vhd._fpf
Normal file
4
Libs/Common/hds/.hdlsidedata/_debounce_rtl.vhd._fpf
Normal file
@ -0,0 +1,4 @@
|
||||
DIALECT atom VHDL_2008
|
||||
INCLUDE list {
|
||||
DEFAULT atom 1
|
||||
}
|
@ -0,0 +1 @@
|
||||
DIALECT atom VHDL_2008
|
1
Libs/Common/hds/.hdlsidedata/_debouncer_RTL.vhd._fpf
Normal file
1
Libs/Common/hds/.hdlsidedata/_debouncer_RTL.vhd._fpf
Normal file
@ -0,0 +1 @@
|
||||
DIALECT atom VHDL_2008
|
1
Libs/Common/hds/.hdlsidedata/_debouncer_entity.vhg._fpf
Normal file
1
Libs/Common/hds/.hdlsidedata/_debouncer_entity.vhg._fpf
Normal file
@ -0,0 +1 @@
|
||||
DIALECT atom VHDL_2008
|
1
Libs/Common/hds/.hdlsidedata/_debouncerulogicvector_entity.vhd._fpf
Executable file
1
Libs/Common/hds/.hdlsidedata/_debouncerulogicvector_entity.vhd._fpf
Executable file
@ -0,0 +1 @@
|
||||
DIALECT atom VHDL_2008
|
@ -0,0 +1 @@
|
||||
DIALECT atom VHDL_2008
|
1
Libs/Common/hds/.hdlsidedata/_edgeDetector_rtl.vhd._fpf
Normal file
1
Libs/Common/hds/.hdlsidedata/_edgeDetector_rtl.vhd._fpf
Normal file
@ -0,0 +1 @@
|
||||
DIALECT atom VHDL_2008
|
1
Libs/Common/hds/.hdlsidedata/_edgedetector_entity.vhd._fpf
Executable file
1
Libs/Common/hds/.hdlsidedata/_edgedetector_entity.vhd._fpf
Executable file
@ -0,0 +1 @@
|
||||
DIALECT atom VHDL_2008
|
@ -0,0 +1 @@
|
||||
DIALECT atom VHDL_2008
|
1
Libs/Common/hds/.hdlsidedata/_rotarytounsigned_entity.vhd._fpf
Executable file
1
Libs/Common/hds/.hdlsidedata/_rotarytounsigned_entity.vhd._fpf
Executable file
@ -0,0 +1 @@
|
||||
DIALECT atom VHDL_2008
|
1
Libs/Common/hds/.hdlsidedata/_spikeFilter_RTL.vhd._fpf
Normal file
1
Libs/Common/hds/.hdlsidedata/_spikeFilter_RTL.vhd._fpf
Normal file
@ -0,0 +1 @@
|
||||
DIALECT atom VHDL_2008
|
1
Libs/Common/hds/.hdlsidedata/_spikefilter_entity.vhd._fpf
Executable file
1
Libs/Common/hds/.hdlsidedata/_spikefilter_entity.vhd._fpf
Executable file
@ -0,0 +1 @@
|
||||
DIALECT atom VHDL_2008
|
@ -0,0 +1 @@
|
||||
DIALECT atom VHDL_2008
|
1
Libs/Common/hds/.hdlsidedata/_toggler_RTL.vhd._fpf
Normal file
1
Libs/Common/hds/.hdlsidedata/_toggler_RTL.vhd._fpf
Normal file
@ -0,0 +1 @@
|
||||
DIALECT atom VHDL_2008
|
1
Libs/Common/hds/.hdlsidedata/_toggler_entity.vhg._fpf
Normal file
1
Libs/Common/hds/.hdlsidedata/_toggler_entity.vhg._fpf
Normal file
@ -0,0 +1 @@
|
||||
DIALECT atom VHDL_2008
|
2
Libs/Common/hds/_blinker._epf
Normal file
2
Libs/Common/hds/_blinker._epf
Normal file
@ -0,0 +1,2 @@
|
||||
DEFAULT_ARCHITECTURE atom arch
|
||||
DEFAULT_FILE atom blinker_arch.vhd
|
2
Libs/Common/hds/_debounce._epf
Normal file
2
Libs/Common/hds/_debounce._epf
Normal file
@ -0,0 +1,2 @@
|
||||
DEFAULT_ARCHITECTURE atom rtl
|
||||
DEFAULT_FILE atom debounce_rtl.vhd
|
2
Libs/Common/hds/_debouncer._epf
Normal file
2
Libs/Common/hds/_debouncer._epf
Normal file
@ -0,0 +1,2 @@
|
||||
DEFAULT_FILE atom debouncer_RTL.vhd
|
||||
DEFAULT_ARCHITECTURE atom rtl
|
2
Libs/Common/hds/_edgedetector._epf
Executable file
2
Libs/Common/hds/_edgedetector._epf
Executable file
@ -0,0 +1,2 @@
|
||||
DEFAULT_ARCHITECTURE atom RTL
|
||||
DEFAULT_FILE atom edgeDetector_rtl.vhd
|
2
Libs/Common/hds/_rotarytounsigned._epf
Executable file
2
Libs/Common/hds/_rotarytounsigned._epf
Executable file
@ -0,0 +1,2 @@
|
||||
DEFAULT_FILE atom rotaryToUnsigned_rtl.vhd
|
||||
DEFAULT_ARCHITECTURE atom rtl
|
2
Libs/Common/hds/_toggler._epf
Normal file
2
Libs/Common/hds/_toggler._epf
Normal file
@ -0,0 +1,2 @@
|
||||
DEFAULT_FILE atom toggler_RTL.vhd
|
||||
DEFAULT_ARCHITECTURE atom rtl
|
1557
Libs/Common/hds/blinker/symbol.sb
Normal file
1557
Libs/Common/hds/blinker/symbol.sb
Normal file
File diff suppressed because it is too large
Load Diff
1586
Libs/Common/hds/debounce/symbol.sb
Normal file
1586
Libs/Common/hds/debounce/symbol.sb
Normal file
File diff suppressed because it is too large
Load Diff
1552
Libs/Common/hds/debouncer/symbol.sb
Normal file
1552
Libs/Common/hds/debouncer/symbol.sb
Normal file
File diff suppressed because it is too large
Load Diff
1576
Libs/Common/hds/debouncer@u@logic@vector/symbol.sb
Normal file
1576
Libs/Common/hds/debouncer@u@logic@vector/symbol.sb
Normal file
File diff suppressed because it is too large
Load Diff
1647
Libs/Common/hds/edge@detector/symbol.sb
Normal file
1647
Libs/Common/hds/edge@detector/symbol.sb
Normal file
File diff suppressed because it is too large
Load Diff
1602
Libs/Common/hds/rotary@to@unsigned/symbol.sb
Normal file
1602
Libs/Common/hds/rotary@to@unsigned/symbol.sb
Normal file
File diff suppressed because it is too large
Load Diff
1552
Libs/Common/hds/spike@filter/symbol.sb
Normal file
1552
Libs/Common/hds/spike@filter/symbol.sb
Normal file
File diff suppressed because it is too large
Load Diff
1552
Libs/Common/hds/toggler/symbol.sb
Normal file
1552
Libs/Common/hds/toggler/symbol.sb
Normal file
File diff suppressed because it is too large
Load Diff
13
Libs/Common_test/hdl/clockGenerator_sim.vhd
Normal file
13
Libs/Common_test/hdl/clockGenerator_sim.vhd
Normal file
@ -0,0 +1,13 @@
|
||||
ARCHITECTURE sim OF clockGenerator IS
|
||||
|
||||
constant clockPeriod: time := (1.0/clockFrequency) * 1 sec;
|
||||
signal clock_int: std_uLogic := '1';
|
||||
|
||||
BEGIN
|
||||
|
||||
reset <= '1', '0' after 2*clockPeriod;
|
||||
|
||||
clock_int <= not clock_int after clockPeriod/2;
|
||||
clock <= transport clock_int after clockPeriod*9.0/10.0;
|
||||
|
||||
END ARCHITECTURE sim;
|
26
Libs/Common_test/hdl/commonLib_tb_test.vhd
Normal file
26
Libs/Common_test/hdl/commonLib_tb_test.vhd
Normal file
@ -0,0 +1,26 @@
|
||||
LIBRARY Common;
|
||||
USE Common.commonLib.all;
|
||||
LIBRARY Common_test;
|
||||
USE Common_test.testUtils.all;
|
||||
|
||||
ARCHITECTURE test OF commonLib_tb IS
|
||||
constant maxPowOf2: positive := 10;
|
||||
constant indent: string(1 to 2) := (others => ' ');
|
||||
BEGIN
|
||||
|
||||
process
|
||||
variable value, bitNb: positive;
|
||||
BEGIN
|
||||
print("testing function " & '"' & "requiredBitNb" & '"');
|
||||
for index in 1 to maxPowOf2 loop
|
||||
for offset in -1 to 1 loop
|
||||
value := 2**index + offset;
|
||||
bitNb := requiredBitNb(value);
|
||||
print(indent & "requiredBitNb(" & sprintf("%d", value) & ") = " & sprintf("%d", bitNb));
|
||||
end loop;
|
||||
print("");
|
||||
end loop;
|
||||
wait;
|
||||
end process;
|
||||
|
||||
END ARCHITECTURE test;
|
141
Libs/Common_test/hdl/debounce_tester_test.vhd
Normal file
141
Libs/Common_test/hdl/debounce_tester_test.vhd
Normal file
@ -0,0 +1,141 @@
|
||||
--
|
||||
-- VHDL Architecture Common_test.debounce_tester.test
|
||||
--
|
||||
-- Created:
|
||||
-- by - remy.borgeat.UNKNOWN (WE10993)
|
||||
-- at - 15:30:08 12.01.2024
|
||||
--
|
||||
-- using Mentor Graphics HDL Designer(TM) 2019.2 (Build 5)
|
||||
--
|
||||
LIBRARY std;
|
||||
USE std.textio.ALL;
|
||||
|
||||
LIBRARY ieee;
|
||||
USE ieee.std_logic_textio.ALL;
|
||||
USE ieee.math_real.all;
|
||||
|
||||
LIBRARY Common_test;
|
||||
USE Common_test.testutils.all;
|
||||
|
||||
ARCHITECTURE test OF debounce_tester IS
|
||||
|
||||
constant clockPeriod : time := 1.0/g_clockFrequency * 1 sec;
|
||||
signal clock_int : std_ulogic := '1';
|
||||
constant DELAY: positive := integer(ceil(((real(g_debounceTime / 1 ps) / 1.0e12) * g_clockFrequency) / real(g_minConsecutiveStateCount))) - 1;
|
||||
|
||||
signal testInfo : string(1 to 40) := (others => ' ');
|
||||
|
||||
BEGIN
|
||||
------------------------------------------------------------------------------
|
||||
-- reset and clock
|
||||
reset <= '1', '0' after 3*clockPeriod;
|
||||
clock_int <= not clock_int after clockPeriod/2;
|
||||
clock <= transport clock_int after clockPeriod*9/10;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- input signal
|
||||
process
|
||||
begin
|
||||
-- startup
|
||||
testInfo <= pad("Init", testInfo'length);
|
||||
input <= '0';
|
||||
wait until reset = '0';
|
||||
wait until clock'event and clock = '1';
|
||||
|
||||
assert (debounced = not g_activeState)
|
||||
report "Startup value should be " & to_string(not g_activeState)
|
||||
severity failure;
|
||||
assert (debounced = g_activeState)
|
||||
report "Value OK"
|
||||
severity note;
|
||||
|
||||
-- transition 0 to 1
|
||||
testInfo <= pad("0 to 1", testInfo'length);
|
||||
input <= '1';
|
||||
wait for (g_minConsecutiveStateCount/2) * DELAY * clockPeriod;
|
||||
assert (debounced = not g_activeState)
|
||||
report "Value should be " & to_string(not g_activeState)
|
||||
severity failure;
|
||||
assert (debounced = g_activeState)
|
||||
report "Value OK"
|
||||
severity note;
|
||||
wait for ((g_minConsecutiveStateCount/2) + 1) * DELAY * clockPeriod;
|
||||
assert (debounced = g_activeState)
|
||||
report "Value should be " & to_string(g_activeState)
|
||||
severity failure;
|
||||
assert (debounced = not g_activeState)
|
||||
report "Value OK"
|
||||
severity note;
|
||||
wait for 100*clockPeriod;
|
||||
|
||||
-- transition 1 to 0
|
||||
testInfo <= pad("1 to 0", testInfo'length);
|
||||
input <= '0';
|
||||
wait for (g_minConsecutiveStateCount/2) * DELAY * clockPeriod;
|
||||
assert (debounced = g_activeState)
|
||||
report "Value should be " & to_string(g_activeState)
|
||||
severity failure;
|
||||
assert (debounced = not g_activeState)
|
||||
report "Value OK"
|
||||
severity note;
|
||||
wait for ((g_minConsecutiveStateCount/2) + 1) * DELAY * clockPeriod;
|
||||
assert (debounced = not g_activeState)
|
||||
report "Value should be " & to_string(not g_activeState)
|
||||
severity failure;
|
||||
assert (debounced = g_activeState)
|
||||
report "Value OK"
|
||||
severity note;
|
||||
wait for 100*clockPeriod;
|
||||
|
||||
|
||||
-- 0 w. glitches
|
||||
testInfo <= pad("0 glitches", testInfo'length);
|
||||
input <= '0',
|
||||
'1' after (g_minConsecutiveStateCount/4) * DELAY * clockPeriod,
|
||||
'0' after (g_minConsecutiveStateCount/2) * DELAY * clockPeriod,
|
||||
'1' after ((g_minConsecutiveStateCount/4)*3) * DELAY * clockPeriod,
|
||||
'0' after (g_minConsecutiveStateCount) * DELAY * clockPeriod;
|
||||
wait for 2 * (g_minConsecutiveStateCount) * DELAY * clockPeriod;
|
||||
assert (debounced = not g_activeState)
|
||||
report "Value should be " & to_string(not g_activeState)
|
||||
severity failure;
|
||||
assert (debounced = g_activeState)
|
||||
report "Value OK"
|
||||
severity note;
|
||||
|
||||
testInfo <= pad("Back to 1", testInfo'length);
|
||||
input <= '1';
|
||||
wait for g_minConsecutiveStateCount * DELAY * clockPeriod;
|
||||
assert (debounced = g_activeState)
|
||||
report "Value should be " & to_string(g_activeState)
|
||||
severity failure;
|
||||
assert (debounced = not g_activeState)
|
||||
report "Value OK"
|
||||
severity note;
|
||||
|
||||
-- 1 w. glitches
|
||||
testInfo <= pad("1 glitches", testInfo'length);
|
||||
input <= '1',
|
||||
'0' after (g_minConsecutiveStateCount/4) * DELAY * clockPeriod,
|
||||
'1' after (g_minConsecutiveStateCount/2) * DELAY * clockPeriod,
|
||||
'0' after ((g_minConsecutiveStateCount/4)*3) * DELAY * clockPeriod,
|
||||
'1' after (g_minConsecutiveStateCount) * DELAY * clockPeriod;
|
||||
wait for 2 * (g_minConsecutiveStateCount) * DELAY * clockPeriod;
|
||||
assert (debounced = g_activeState)
|
||||
report "Value should be " & to_string(g_activeState)
|
||||
severity failure;
|
||||
assert (debounced = not g_activeState)
|
||||
report "Value OK"
|
||||
severity note;
|
||||
|
||||
-- end of simulation
|
||||
testInfo <= pad("End", testInfo'length);
|
||||
wait for 10*clockPeriod;
|
||||
assert false
|
||||
report "End of simulation"
|
||||
severity failure;
|
||||
wait;
|
||||
end process;
|
||||
|
||||
END ARCHITECTURE test;
|
||||
|
57
Libs/Common_test/hdl/debouncerULogicVector_tester_RTL.vhd
Normal file
57
Libs/Common_test/hdl/debouncerULogicVector_tester_RTL.vhd
Normal file
@ -0,0 +1,57 @@
|
||||
ARCHITECTURE RTL OF debouncerULogicVector_tester IS
|
||||
|
||||
constant clockFrequency : real := 100.0E6;
|
||||
constant clockPeriod : time := 1.0/clockFrequency * 1 sec;
|
||||
signal clock_int : std_ulogic := '1';
|
||||
|
||||
constant longDelay : time := 2**(counterBitNb+1) * clockPeriod;
|
||||
|
||||
BEGIN
|
||||
------------------------------------------------------------------------------
|
||||
-- reset and clock
|
||||
reset <= '1', '0' after 3*clockPeriod;
|
||||
clock_int <= not clock_int after clockPeriod/2;
|
||||
clock <= transport clock_int after clockPeriod*9/10;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- input signal
|
||||
process
|
||||
begin
|
||||
input <= (others => '0');
|
||||
wait for longDelay;
|
||||
-- transition 0 to 1
|
||||
input(1) <= '1',
|
||||
'0' after 1*clockPeriod,
|
||||
'1' after 3*clockPeriod,
|
||||
'0' after 5*clockPeriod,
|
||||
'1' after 6*clockPeriod,
|
||||
'0' after 8*clockPeriod,
|
||||
'1' after 10*clockPeriod;
|
||||
wait for longDelay;
|
||||
-- transition to other bit
|
||||
-- transition 1 to 0
|
||||
input(1) <= '0';
|
||||
wait for longDelay;
|
||||
input(2) <= '1';
|
||||
wait for longDelay;
|
||||
-- transition 1 to 0
|
||||
input(2) <= '0',
|
||||
'1' after 1*clockPeriod,
|
||||
'0' after 3*clockPeriod,
|
||||
'1' after 5*clockPeriod,
|
||||
'0' after 6*clockPeriod,
|
||||
'1' after 8*clockPeriod,
|
||||
'0' after 10*clockPeriod;
|
||||
wait for longDelay;
|
||||
-- short 1 pulse
|
||||
input(3) <= '1',
|
||||
'0' after 1*clockPeriod,
|
||||
'1' after 3*clockPeriod,
|
||||
'0' after 5*clockPeriod,
|
||||
'1' after 6*clockPeriod,
|
||||
'0' after 8*clockPeriod;
|
||||
-- end of simulation
|
||||
wait;
|
||||
end process;
|
||||
|
||||
END ARCHITECTURE RTL;
|
49
Libs/Common_test/hdl/debouncer_tester_test.vhd
Normal file
49
Libs/Common_test/hdl/debouncer_tester_test.vhd
Normal file
@ -0,0 +1,49 @@
|
||||
ARCHITECTURE test OF debouncer_tester IS
|
||||
|
||||
constant clockFrequency : real := 66.0E6;
|
||||
constant clockPeriod : time := 1.0/clockFrequency * 1 sec;
|
||||
signal clock_int : std_ulogic := '1';
|
||||
|
||||
BEGIN
|
||||
------------------------------------------------------------------------------
|
||||
-- reset and clock
|
||||
reset <= '1', '0' after 3*clockPeriod;
|
||||
clock_int <= not clock_int after clockPeriod/2;
|
||||
clock <= transport clock_int after clockPeriod*9/10;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- input signal
|
||||
process
|
||||
begin
|
||||
input <= '0';
|
||||
wait for 10*clockPeriod;
|
||||
-- transition 0 to 1
|
||||
input <= '1',
|
||||
'0' after 1*clockPeriod,
|
||||
'1' after 3*clockPeriod,
|
||||
'0' after 5*clockPeriod,
|
||||
'1' after 6*clockPeriod,
|
||||
'0' after 8*clockPeriod,
|
||||
'1' after 10*clockPeriod;
|
||||
wait for 50*clockPeriod;
|
||||
-- transition 1 to 0
|
||||
input <= '0',
|
||||
'1' after 1*clockPeriod,
|
||||
'0' after 3*clockPeriod,
|
||||
'1' after 5*clockPeriod,
|
||||
'0' after 6*clockPeriod,
|
||||
'1' after 8*clockPeriod,
|
||||
'0' after 10*clockPeriod;
|
||||
wait for 50*clockPeriod;
|
||||
-- short 1 pulse
|
||||
input <= '1',
|
||||
'0' after 1*clockPeriod,
|
||||
'1' after 3*clockPeriod,
|
||||
'0' after 5*clockPeriod,
|
||||
'1' after 6*clockPeriod,
|
||||
'0' after 8*clockPeriod;
|
||||
-- end of simulation
|
||||
wait;
|
||||
end process;
|
||||
|
||||
END ARCHITECTURE test;
|
40
Libs/Common_test/hdl/requiredBitNb.txt
Normal file
40
Libs/Common_test/hdl/requiredBitNb.txt
Normal file
@ -0,0 +1,40 @@
|
||||
# testing function "requiredBitNb"
|
||||
# requiredBitNb(1) = 1
|
||||
# requiredBitNb(2) = 2
|
||||
# requiredBitNb(3) = 2
|
||||
#
|
||||
# requiredBitNb(3) = 2
|
||||
# requiredBitNb(4) = 3
|
||||
# requiredBitNb(5) = 3
|
||||
#
|
||||
# requiredBitNb(7) = 3
|
||||
# requiredBitNb(8) = 4
|
||||
# requiredBitNb(9) = 4
|
||||
#
|
||||
# requiredBitNb(15) = 4
|
||||
# requiredBitNb(16) = 5
|
||||
# requiredBitNb(17) = 5
|
||||
#
|
||||
# requiredBitNb(31) = 5
|
||||
# requiredBitNb(32) = 6
|
||||
# requiredBitNb(33) = 6
|
||||
#
|
||||
# requiredBitNb(63) = 6
|
||||
# requiredBitNb(64) = 7
|
||||
# requiredBitNb(65) = 7
|
||||
#
|
||||
# requiredBitNb(127) = 7
|
||||
# requiredBitNb(128) = 8
|
||||
# requiredBitNb(129) = 8
|
||||
#
|
||||
# requiredBitNb(255) = 8
|
||||
# requiredBitNb(256) = 9
|
||||
# requiredBitNb(257) = 9
|
||||
#
|
||||
# requiredBitNb(511) = 9
|
||||
# requiredBitNb(512) = 10
|
||||
# requiredBitNb(513) = 10
|
||||
#
|
||||
# requiredBitNb(1023) = 10
|
||||
# requiredBitNb(1024) = 11
|
||||
# requiredBitNb(1025) = 11
|
47
Libs/Common_test/hdl/rotaryToUnsigned_tester_test.vhd
Normal file
47
Libs/Common_test/hdl/rotaryToUnsigned_tester_test.vhd
Normal file
@ -0,0 +1,47 @@
|
||||
ARCHITECTURE test OF rotaryToUnsigned_tester IS
|
||||
|
||||
constant clockFrequency : real := 100.0E6;
|
||||
constant clockPeriod : time := 1.0/clockFrequency * 1 sec;
|
||||
signal clock_int : std_ulogic := '1';
|
||||
|
||||
constant stepPeriod : time := 100*clockPeriod;
|
||||
signal rotary_int : unsigned(rotary'range);
|
||||
|
||||
BEGIN
|
||||
------------------------------------------------------------------------------
|
||||
-- reset and clock
|
||||
reset <= '1', '0' after 3*clockPeriod;
|
||||
clock_int <= not clock_int after clockPeriod/2;
|
||||
clock <= transport clock_int after clockPeriod*9/10;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- input signal
|
||||
turnRotary: process
|
||||
begin
|
||||
rotary_int <= (others => '0');
|
||||
wait for 10*stepPeriod;
|
||||
-- count over max value
|
||||
for index in 1 to 2**outputBitNb+2 loop
|
||||
rotary_int <= rotary_int + 1;
|
||||
wait for stepPeriod;
|
||||
end loop;
|
||||
-- count down again
|
||||
for index in 1 to 2**outputBitNb+2 loop
|
||||
rotary_int <= rotary_int - 1;
|
||||
wait for stepPeriod;
|
||||
end loop;
|
||||
-- end of simulation
|
||||
wait;
|
||||
end process turnRotary;
|
||||
|
||||
addGlitches: process
|
||||
begin
|
||||
wait on rotary_int;
|
||||
rotary <= (others => '0');
|
||||
wait for clockPeriod;
|
||||
rotary <= (others => '1');
|
||||
wait for clockPeriod;
|
||||
rotary <= rotary_int;
|
||||
end process addGlitches;
|
||||
|
||||
END ARCHITECTURE test;
|
47
Libs/Common_test/hdl/spikeFilter_tester_test.vhd
Normal file
47
Libs/Common_test/hdl/spikeFilter_tester_test.vhd
Normal file
@ -0,0 +1,47 @@
|
||||
ARCHITECTURE test OF spikeFilter_tester IS
|
||||
|
||||
constant clockFrequency : real := 100.0E6;
|
||||
constant clockPeriod : time := 1.0/clockFrequency * 1 sec;
|
||||
signal clock_int : std_ulogic := '1';
|
||||
|
||||
BEGIN
|
||||
------------------------------------------------------------------------------
|
||||
-- reset and clock
|
||||
reset <= '1', '0' after 3*clockPeriod;
|
||||
clock_int <= not clock_int after clockPeriod/2;
|
||||
clock <= transport clock_int after clockPeriod*9/10;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- input signal
|
||||
process
|
||||
begin
|
||||
input <= '0';
|
||||
wait for 10*clockPeriod;
|
||||
-- loop on pulse width
|
||||
for pulseWidth in 1 to 10 loop
|
||||
-- send positive pulses train
|
||||
for index in 1 to 8 loop
|
||||
input <= '1';
|
||||
wait for pulseWidth * clockPeriod;
|
||||
input <= '0';
|
||||
wait for pulseWidth * clockPeriod;
|
||||
end loop;
|
||||
-- set input high
|
||||
input <= '1';
|
||||
wait for 100*clockPeriod;
|
||||
-- send negative pulses train
|
||||
for index in 1 to 8 loop
|
||||
input <= '0';
|
||||
wait for pulseWidth * clockPeriod;
|
||||
input <= '1';
|
||||
wait for pulseWidth * clockPeriod;
|
||||
end loop;
|
||||
-- set input low
|
||||
input <= '0';
|
||||
wait for 100*clockPeriod;
|
||||
end loop;
|
||||
-- end of simulation
|
||||
wait;
|
||||
end process;
|
||||
|
||||
END ARCHITECTURE test;
|
127
Libs/Common_test/hdl/testUtils_pkg.vhd
Normal file
127
Libs/Common_test/hdl/testUtils_pkg.vhd
Normal file
@ -0,0 +1,127 @@
|
||||
LIBRARY std;
|
||||
USE std.textio.all;
|
||||
LIBRARY ieee;
|
||||
USE ieee.std_logic_1164.all;
|
||||
USE ieee.numeric_std.all;
|
||||
|
||||
PACKAGE testUtils IS
|
||||
|
||||
--============================================================================
|
||||
-- console output
|
||||
--
|
||||
|
||||
procedure print(value : string);
|
||||
|
||||
|
||||
--============================================================================
|
||||
-- string manipulation
|
||||
--
|
||||
|
||||
-- conversion to lowercase
|
||||
function lc(value : string) return string;
|
||||
procedure lc(value : inout line);
|
||||
-- conversion to uppercase
|
||||
function uc(value : string) return string;
|
||||
procedure uc(value : inout line);
|
||||
-- expand a string to a given length
|
||||
function pad(
|
||||
value : string;
|
||||
string_length : natural;
|
||||
fill_char : character := ' ';
|
||||
right_justify : boolean := false
|
||||
) return string;
|
||||
-- remove separator characters at beginning and end of line
|
||||
procedure rm_side_separators(
|
||||
value : inout line;
|
||||
separators : in string
|
||||
);
|
||||
procedure rm_side_separators(
|
||||
value : inout line
|
||||
);
|
||||
-- remove multiple occurences of separator characters
|
||||
procedure trim_line(
|
||||
value : inout line;
|
||||
separators : in string
|
||||
);
|
||||
|
||||
procedure trim_line(
|
||||
value : inout line
|
||||
);
|
||||
-- remove all occurences of separator characters
|
||||
procedure rm_all_separators(
|
||||
value : inout line;
|
||||
separators : in string
|
||||
);
|
||||
|
||||
procedure rm_all_separators(
|
||||
value : inout line
|
||||
);
|
||||
-- find and remove first word
|
||||
procedure read_first(
|
||||
value : inout line;
|
||||
separators : in string;
|
||||
first : out line
|
||||
);
|
||||
|
||||
procedure read_first(
|
||||
value : inout line;
|
||||
first : out line
|
||||
);
|
||||
-- find and remove last word
|
||||
procedure read_last(
|
||||
value : inout line;
|
||||
separators : in string;
|
||||
last : out line
|
||||
);
|
||||
|
||||
procedure read_last(
|
||||
value : inout line;
|
||||
last : out line
|
||||
);
|
||||
|
||||
|
||||
--============================================================================
|
||||
-- formatted string output
|
||||
--
|
||||
-- format codes:
|
||||
-- code integer real std_logic std_(u)logic_vector (un)signed time
|
||||
-- b v v v v binary
|
||||
-- c character
|
||||
-- d v v v v v decimal
|
||||
-- e real numbers, with power of 10 exponent
|
||||
-- f v v fixed point real numbers
|
||||
-- s string
|
||||
-- ts v time in seconds
|
||||
-- tm v time in milliseconds
|
||||
-- tu v time in microseconds
|
||||
-- tn v time in nanoseconds
|
||||
-- tp v time in picoseconds
|
||||
-- x v v v v hexadecimal
|
||||
-- X v v v v hexadecimal with upper-case letters
|
||||
|
||||
function sprintf(format : string; value : integer ) return string;
|
||||
function sprintf(format : string; value : real ) return string;
|
||||
function sprintf(format : string; value : std_logic ) return string;
|
||||
function sprintf(format : string; value : std_ulogic_vector) return string;
|
||||
function sprintf(format : string; value : std_logic_vector ) return string;
|
||||
function sprintf(format : string; value : unsigned ) return string;
|
||||
function sprintf(format : string; value : signed ) return string;
|
||||
function sprintf(format : string; value : time ) return string;
|
||||
|
||||
--============================================================================
|
||||
-- formatted string input
|
||||
--
|
||||
subtype nibbleUlogicType is std_ulogic_vector(3 downto 0);
|
||||
subtype nibbleUnsignedType is unsigned(3 downto 0);
|
||||
|
||||
function sscanf(value : character) return natural;
|
||||
function sscanf(value : character) return nibbleUlogicType;
|
||||
function sscanf(value : character) return nibbleUnsignedType;
|
||||
function sscanf(value : string ) return natural;
|
||||
function sscanf(value : string ) return unsigned;
|
||||
function sscanf(value : string ) return std_ulogic_vector;
|
||||
function sscanf(value : string ) return time;
|
||||
|
||||
procedure sscanf(value : inout line; time_val : out time);
|
||||
|
||||
END testUtils;
|
924
Libs/Common_test/hdl/testUtils_pkg_body.vhd
Normal file
924
Libs/Common_test/hdl/testUtils_pkg_body.vhd
Normal file
@ -0,0 +1,924 @@
|
||||
PACKAGE BODY testUtils IS
|
||||
|
||||
--============================================================================
|
||||
-- console output
|
||||
--
|
||||
|
||||
procedure print(value : string) is
|
||||
variable my_line : line;
|
||||
begin
|
||||
write(my_line, value);
|
||||
writeLine(output, my_line);
|
||||
deallocate(my_line);
|
||||
end print;
|
||||
|
||||
|
||||
--============================================================================
|
||||
-- string manipulation
|
||||
--
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- change to lowercase
|
||||
------------------------------------------------------------------------------
|
||||
procedure lc(value: inout line) is
|
||||
variable out_line: line;
|
||||
begin
|
||||
for index in value'range loop
|
||||
if (value(index) >= 'A') and (value(index) <= 'Z') then
|
||||
value(index) := character'val(character'pos(value(index))
|
||||
- character'pos('A')
|
||||
+ character'pos('a')
|
||||
);
|
||||
end if;
|
||||
end loop;
|
||||
end lc;
|
||||
|
||||
function lc(value: string) return string is
|
||||
variable out_line: line;
|
||||
begin
|
||||
write(out_line, value);
|
||||
lc(out_line);
|
||||
return(out_line.all);
|
||||
end lc;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- change to uppercase
|
||||
------------------------------------------------------------------------------
|
||||
procedure uc(value: inout line) is
|
||||
variable out_line: line;
|
||||
begin
|
||||
for index in value'range loop
|
||||
if (value(index) >= 'a') and (value(index) <= 'z') then
|
||||
value(index) := character'val(character'pos(value(index))
|
||||
- character'pos('a')
|
||||
+ character'pos('A')
|
||||
);
|
||||
end if;
|
||||
end loop;
|
||||
end uc;
|
||||
|
||||
function uc(value: string) return string is
|
||||
variable out_line: line;
|
||||
begin
|
||||
write(out_line, value);
|
||||
uc(out_line);
|
||||
return(out_line.all);
|
||||
end uc;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- formatted string output: padding and justifying
|
||||
------------------------------------------------------------------------------
|
||||
function pad(
|
||||
value : string;
|
||||
string_length : natural;
|
||||
fill_char : character := ' ';
|
||||
right_justify : boolean := false
|
||||
) return string is
|
||||
variable value_line : line;
|
||||
variable out_line : line;
|
||||
variable value_length : natural;
|
||||
variable shift_sign : boolean;
|
||||
begin
|
||||
write(value_line, value);
|
||||
value_length := value_line.all'length;
|
||||
if string_length = 0 then
|
||||
write(out_line, value_line.all);
|
||||
elsif string_length > value_length then
|
||||
if right_justify then
|
||||
if (value_line.all(value_line.all'left) <= '-') and not(fill_char = ' ') then
|
||||
shift_sign := true;
|
||||
write(out_line, value_line.all(value_line.all'left));
|
||||
end if;
|
||||
for index in 1 to string_length-value_length loop
|
||||
write(out_line, fill_char);
|
||||
end loop;
|
||||
end if;
|
||||
if shift_sign then
|
||||
write(out_line, value_line.all(value_line.all'left+1 to value_line.all'right));
|
||||
else
|
||||
write(out_line, value_line.all);
|
||||
end if;
|
||||
if not right_justify then
|
||||
for index in 1 to string_length-value_length loop
|
||||
write(out_line, fill_char);
|
||||
end loop;
|
||||
end if;
|
||||
elsif string_length < value_length then
|
||||
write(out_line, '#');
|
||||
write(out_line, value_line.all(value_length-string_length+2 to value_length));
|
||||
else
|
||||
write(out_line, value_line.all);
|
||||
end if;
|
||||
deallocate(value_line);
|
||||
return(out_line.all);
|
||||
end pad;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- remove separator characters at beginning and end of line
|
||||
------------------------------------------------------------------------------
|
||||
procedure rm_side_separators(
|
||||
value : inout line;
|
||||
separators : in string
|
||||
) is
|
||||
variable input_line : line := value;
|
||||
variable found : boolean := false;
|
||||
variable position : integer := 0;
|
||||
begin
|
||||
-- remove all separators in the beginning
|
||||
position := -1;
|
||||
for character_index in input_line'range loop
|
||||
found := false;
|
||||
for separator_index in separators'range loop
|
||||
if input_line(character_index) = separators(separator_index) then
|
||||
found := true;
|
||||
end if;
|
||||
end loop;
|
||||
if found then
|
||||
position := character_index;
|
||||
else
|
||||
exit;
|
||||
end if;
|
||||
end loop;
|
||||
if position > -1 then
|
||||
input_line := new string'( input_line(position+1 to input_line'right) );
|
||||
end if;
|
||||
|
||||
-- remove all separators in the end
|
||||
position := -1;
|
||||
for character_index in input_line'reverse_range loop
|
||||
found := false;
|
||||
for separator_index in separators'range loop
|
||||
if input_line(character_index) = separators(separator_index) then
|
||||
found := true;
|
||||
end if;
|
||||
end loop;
|
||||
if found then
|
||||
position := character_index;
|
||||
else
|
||||
exit;
|
||||
end if;
|
||||
end loop;
|
||||
if position > -1 then
|
||||
input_line := new string'( input_line(input_line'left to position-1) );
|
||||
end if;
|
||||
|
||||
value := input_line;
|
||||
end;
|
||||
|
||||
procedure rm_side_separators(value : inout line) is
|
||||
begin
|
||||
rm_side_separators(value, " :" & ht);
|
||||
end;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- remove multiple occurences of separator characters, keeping one single
|
||||
------------------------------------------------------------------------------
|
||||
procedure trim_line(
|
||||
value : inout line;
|
||||
separators : in string
|
||||
) is
|
||||
variable input_line: line := value;
|
||||
variable output_line: line := new string'("");
|
||||
variable is_separator, was_separator : boolean := false;
|
||||
begin
|
||||
rm_side_separators(input_line);
|
||||
for character_index in input_line'range loop
|
||||
is_separator := false;
|
||||
for separator_index in separators'range loop
|
||||
if input_line.all(character_index) = separators(separator_index) then
|
||||
is_separator := true;
|
||||
end if;
|
||||
end loop;
|
||||
if not (is_separator and was_separator) then
|
||||
write(output_line, input_line.all(character_index));
|
||||
end if;
|
||||
was_separator := is_separator;
|
||||
end loop;
|
||||
|
||||
value := output_line;
|
||||
end;
|
||||
|
||||
procedure trim_line(value : inout line) is
|
||||
begin
|
||||
trim_line(value, " :" & ht);
|
||||
end;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- remove all occurences of separator characters
|
||||
------------------------------------------------------------------------------
|
||||
procedure rm_all_separators(
|
||||
value : inout line;
|
||||
separators : in string
|
||||
) is
|
||||
variable input_line : line := value;
|
||||
variable is_separator : boolean := false;
|
||||
begin
|
||||
|
||||
-- remove separators from beginn and end of the line
|
||||
-- rm_separator_be(value, separators);
|
||||
|
||||
-- empty output line
|
||||
value := new string'("");
|
||||
|
||||
-- find all separator symbols
|
||||
for character_index in input_line'range loop
|
||||
is_separator := false;
|
||||
for separator_index in separators'range loop
|
||||
if input_line(character_index) = separators(separator_index) then
|
||||
is_separator := true;
|
||||
end if;
|
||||
end loop;
|
||||
if not is_separator then
|
||||
write(value, input_line.all(character_index));
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
end;
|
||||
|
||||
procedure rm_all_separators(value : inout line) is
|
||||
begin
|
||||
rm_all_separators(value, " _." & ht);
|
||||
end;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- read first "word" out of a line
|
||||
------------------------------------------------------------------------------
|
||||
procedure read_first(
|
||||
value : inout line;
|
||||
separators : in string;
|
||||
first : out line
|
||||
) is
|
||||
variable input_line: line;
|
||||
variable position: natural := 0;
|
||||
begin
|
||||
input_line := value;
|
||||
for character_index in input_line.all'reverse_range loop
|
||||
for separator_index in separators'range loop
|
||||
if input_line.all(character_index) = separators(separator_index) then
|
||||
position := character_index;
|
||||
end if;
|
||||
end loop;
|
||||
end loop;
|
||||
if position > 1 then
|
||||
first := new string'(input_line.all(input_line'left to position-1));
|
||||
value := new string'(input_line(position+1 to input_line'right));
|
||||
else
|
||||
first := new string'(input_line.all);
|
||||
value := new string'("");
|
||||
end if;
|
||||
end;
|
||||
|
||||
procedure read_first(value : inout line; first : out line) is
|
||||
begin
|
||||
read_first(value, " :" & ht, first);
|
||||
end;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- read last "word" out of a line
|
||||
------------------------------------------------------------------------------
|
||||
procedure read_last(
|
||||
value : inout line;
|
||||
separators : in string;
|
||||
last : out line
|
||||
) is
|
||||
variable input_line: line := value;
|
||||
variable position: natural := 0;
|
||||
begin
|
||||
for character_index in input_line'range loop
|
||||
for separator_index in separators'range loop
|
||||
if input_line(character_index) = separators(separator_index) then
|
||||
position := character_index;
|
||||
end if;
|
||||
end loop;
|
||||
end loop;
|
||||
if position <= input_line'right and
|
||||
position > 0 then
|
||||
value := new string'(input_line(input_line'left to position-1));
|
||||
last := new string'(input_line(position+1 to input_line'right));
|
||||
else
|
||||
last := new string'(input_line.all);
|
||||
end if;
|
||||
end;
|
||||
|
||||
procedure read_last(value : inout line; last : out line) is
|
||||
begin
|
||||
read_last(value, " :" & ht, last);
|
||||
end;
|
||||
|
||||
|
||||
--============================================================================
|
||||
-- formatted string output, internal functions
|
||||
--
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- get format specification
|
||||
------------------------------------------------------------------------------
|
||||
procedure get_format_items(
|
||||
format : string;
|
||||
right_justify : out boolean;
|
||||
add_sign : out boolean;
|
||||
fill_char : out character;
|
||||
total_length : out natural;
|
||||
point_precision : out natural;
|
||||
format_type : inout line
|
||||
) is
|
||||
variable find_sign : boolean := false;
|
||||
variable find_padding : boolean := false;
|
||||
variable find_length : boolean := false;
|
||||
variable find_precision : boolean := false;
|
||||
variable find_type : boolean := false;
|
||||
variable right_justify_int : boolean := true;
|
||||
variable total_length_int : natural := 0;
|
||||
variable point_precision_int : natural := 0;
|
||||
begin
|
||||
add_sign := false;
|
||||
fill_char := ' ';
|
||||
for index in 1 to format'length loop
|
||||
if find_type then
|
||||
write(format_type, format(index));
|
||||
end if;
|
||||
if find_precision then
|
||||
if (format(index) >= '0') and (format(index) <= '9') then
|
||||
point_precision_int := 10*point_precision_int + character'pos(format(index)) - character'pos('0');
|
||||
if format(index+1) >= 'A' then
|
||||
find_precision := false;
|
||||
find_type := true;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
if find_length then
|
||||
if (format(index) >= '0') and (format(index) <= '9') then
|
||||
total_length_int := 10*total_length_int + character'pos(format(index)) - character'pos('0');
|
||||
end if;
|
||||
if format(index) = '.' then
|
||||
find_length := false;
|
||||
find_precision := true;
|
||||
elsif format(index+1) >= 'A' then
|
||||
find_length := false;
|
||||
find_type := true;
|
||||
end if;
|
||||
end if;
|
||||
if find_padding then
|
||||
if format(index) = '0' then
|
||||
if right_justify_int then
|
||||
fill_char := '0';
|
||||
end if;
|
||||
end if;
|
||||
find_padding := false;
|
||||
if format(index+1) >= 'A' then
|
||||
find_type := true;
|
||||
else
|
||||
find_length := true;
|
||||
end if;
|
||||
end if;
|
||||
if find_sign then
|
||||
if format(index) = '-' then
|
||||
right_justify_int := false;
|
||||
end if;
|
||||
if format(index) = '+' then
|
||||
add_sign := true;
|
||||
end if;
|
||||
find_sign := false;
|
||||
if format(index+1) <= '-' then
|
||||
find_sign := true;
|
||||
elsif format(index+1) = '0' then
|
||||
find_padding := true;
|
||||
elsif format(index+1) >= 'A' then
|
||||
find_type := true;
|
||||
else
|
||||
find_length := true;
|
||||
end if;
|
||||
end if;
|
||||
if format(index) = '%' then
|
||||
if format(index+1) <= '-' then
|
||||
find_sign := true;
|
||||
elsif format(index+1) = '0' then
|
||||
find_padding := true;
|
||||
elsif format(index+1) >= 'A' then
|
||||
find_type := true;
|
||||
else
|
||||
find_length := true;
|
||||
end if;
|
||||
end if;
|
||||
end loop;
|
||||
right_justify := right_justify_int;
|
||||
total_length := total_length_int;
|
||||
point_precision := point_precision_int;
|
||||
end get_format_items;
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- formatted string output: converting std_ulogic to character
|
||||
------------------------------------------------------------------------------
|
||||
function to_character(value: std_ulogic) return character is
|
||||
variable out_value: character;
|
||||
begin
|
||||
case value is
|
||||
when 'U' => out_value := 'U';
|
||||
when 'X' => out_value := 'X';
|
||||
when '0' => out_value := '0';
|
||||
when '1' => out_value := '1';
|
||||
when 'Z' => out_value := 'Z';
|
||||
when 'W' => out_value := 'W';
|
||||
when 'L' => out_value := 'L';
|
||||
when 'H' => out_value := 'H';
|
||||
when '-' => out_value := '-';
|
||||
end case;
|
||||
return(out_value);
|
||||
end to_character;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- formatted string output: binary integer
|
||||
------------------------------------------------------------------------------
|
||||
function sprintf_b(value: std_ulogic_vector) return string is
|
||||
variable out_line : line;
|
||||
begin
|
||||
for index in value'range loop
|
||||
write(out_line, to_character(value(index)));
|
||||
end loop;
|
||||
return(out_line.all);
|
||||
end sprintf_b;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- formatted string output: decimal integer
|
||||
------------------------------------------------------------------------------
|
||||
function sprintf_d(
|
||||
right_justify : boolean;
|
||||
add_sign : boolean;
|
||||
fill_char : character;
|
||||
string_length : natural;
|
||||
value : integer
|
||||
) return string is
|
||||
variable value_line : line;
|
||||
begin
|
||||
if add_sign and (value >= 0) then
|
||||
write(value_line, '+');
|
||||
end if;
|
||||
write(value_line, value);
|
||||
if string_length = 0 then
|
||||
return(value_line.all);
|
||||
else
|
||||
return(pad(value_line.all, string_length, fill_char, right_justify));
|
||||
end if;
|
||||
end sprintf_d;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- formatted string output: fixed point real
|
||||
------------------------------------------------------------------------------
|
||||
function sprintf_f(
|
||||
right_justify : boolean;
|
||||
add_sign : boolean;
|
||||
fill_char : character;
|
||||
string_length : natural;
|
||||
point_precision : natural;
|
||||
value : real
|
||||
) return string is
|
||||
variable point_precision_int : natural;
|
||||
variable integer_part : integer;
|
||||
variable decimal_part : natural;
|
||||
variable value_line : line;
|
||||
begin
|
||||
if point_precision = 0 then
|
||||
point_precision_int := 6;
|
||||
else
|
||||
point_precision_int := point_precision;
|
||||
end if;
|
||||
if value >= 0.0 then
|
||||
integer_part := integer(value-0.5);
|
||||
else
|
||||
integer_part := - integer(-value-0.5);
|
||||
end if;
|
||||
decimal_part := abs(integer((value-real(integer_part))*(10.0**point_precision_int)));
|
||||
if add_sign and (value >= 0.0) then
|
||||
write(value_line, '+');
|
||||
end if;
|
||||
write(value_line, integer_part);
|
||||
write(value_line, '.');
|
||||
write(value_line, sprintf_d(true, false, '0', point_precision_int, decimal_part));
|
||||
if string_length = 0 then
|
||||
return(value_line.all);
|
||||
else
|
||||
return(pad(value_line.all, string_length, fill_char, right_justify));
|
||||
end if;
|
||||
end sprintf_f;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- formatted string output: hexadecimal integer
|
||||
------------------------------------------------------------------------------
|
||||
function sprintf_X(
|
||||
extend_unsigned : boolean;
|
||||
value : std_ulogic_vector
|
||||
) return string is
|
||||
variable bit_count : positive;
|
||||
variable value_line : line;
|
||||
variable out_line : line;
|
||||
variable nibble: string(1 to 4);
|
||||
begin
|
||||
bit_count := value'length;
|
||||
while (bit_count mod 4) /= 0 loop
|
||||
if extend_unsigned then
|
||||
write(value_line, to_character('0'));
|
||||
else
|
||||
write(value_line, to_character(value(value'high)));
|
||||
end if;
|
||||
bit_count := bit_count + 1;
|
||||
end loop;
|
||||
write(value_line, sprintf_b(value));
|
||||
for index in value_line.all'range loop
|
||||
if (index mod 4) = 0 then
|
||||
nibble := value_line.all(index-3 to index);
|
||||
case nibble is
|
||||
when "0000" => write(out_line, 0);
|
||||
when "0001" => write(out_line, 1);
|
||||
when "0010" => write(out_line, 2);
|
||||
when "0011" => write(out_line, 3);
|
||||
when "0100" => write(out_line, 4);
|
||||
when "0101" => write(out_line, 5);
|
||||
when "0110" => write(out_line, 6);
|
||||
when "0111" => write(out_line, 7);
|
||||
when "1000" => write(out_line, 8);
|
||||
when "1001" => write(out_line, 9);
|
||||
when "1010" => write(out_line, 'A');
|
||||
when "1011" => write(out_line, 'B');
|
||||
when "1100" => write(out_line, 'C');
|
||||
when "1101" => write(out_line, 'D');
|
||||
when "1110" => write(out_line, 'E');
|
||||
when "1111" => write(out_line, 'F');
|
||||
when others => write(out_line, 'X');
|
||||
end case;
|
||||
end if;
|
||||
end loop;
|
||||
return(out_line.all);
|
||||
end sprintf_X;
|
||||
|
||||
|
||||
--============================================================================
|
||||
-- formatted string output, interface functions
|
||||
--
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- integer
|
||||
------------------------------------------------------------------------------
|
||||
function sprintf(format : string; value : integer) return string is
|
||||
variable right_justify : boolean;
|
||||
variable add_sign : boolean;
|
||||
variable fill_char : character;
|
||||
variable string_length : natural;
|
||||
variable point_precision : natural;
|
||||
variable format_type : line;
|
||||
begin
|
||||
get_format_items(format, right_justify, add_sign, fill_char,
|
||||
string_length, point_precision, format_type);
|
||||
if format_type.all = "b" then
|
||||
if string_length = 0 then
|
||||
string_length := 8;
|
||||
end if;
|
||||
return(sprintf_b(std_ulogic_vector(to_signed(value, string_length+1)(string_length-1 downto 0))));
|
||||
elsif format_type.all = "d" then
|
||||
return(sprintf_d(right_justify, add_sign, fill_char, string_length, value));
|
||||
elsif format_type.all = "f" then
|
||||
return(sprintf_f(right_justify, add_sign, fill_char,
|
||||
string_length, point_precision, real(value)));
|
||||
elsif (format_type.all = "X") or (format_type.all = "x") then
|
||||
if string_length = 0 then
|
||||
string_length := 8;
|
||||
end if;
|
||||
string_length := 4*string_length;
|
||||
if format_type.all = "X" then
|
||||
return(sprintf_X(false, std_ulogic_vector(to_signed(value, string_length+1)(string_length-1 downto 0))));
|
||||
else
|
||||
return(lc(sprintf_X(false, std_ulogic_vector(to_signed(value, string_length+1)(string_length-1 downto 0)))));
|
||||
end if;
|
||||
else
|
||||
return("Unhandled format type: '" & format_type.all & "'");
|
||||
end if;
|
||||
end sprintf;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- real
|
||||
------------------------------------------------------------------------------
|
||||
function sprintf(format : string; value : real) return string is
|
||||
variable right_justify : boolean;
|
||||
variable add_sign : boolean;
|
||||
variable fill_char : character;
|
||||
variable string_length : natural;
|
||||
variable point_precision : natural;
|
||||
variable format_type : line;
|
||||
begin
|
||||
get_format_items(format, right_justify, add_sign, fill_char,
|
||||
string_length, point_precision, format_type);
|
||||
if (format_type.all = "d") or (point_precision = 0) then
|
||||
return(sprintf_d(right_justify, add_sign, fill_char,
|
||||
string_length, integer(value)));
|
||||
elsif format_type.all = "f" then
|
||||
return(sprintf_f(right_justify, add_sign, fill_char,
|
||||
string_length, point_precision, value));
|
||||
else
|
||||
return("Unhandled format type: '" & format_type.all & "'");
|
||||
end if;
|
||||
end sprintf;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- std_logic
|
||||
------------------------------------------------------------------------------
|
||||
function sprintf(format : string; value : std_logic) return string is
|
||||
variable right_justify : boolean;
|
||||
variable add_sign : boolean;
|
||||
variable fill_char : character;
|
||||
variable string_length : natural;
|
||||
variable point_precision : natural;
|
||||
variable format_type : line;
|
||||
variable logic_vector: std_logic_vector(1 to 1);
|
||||
begin
|
||||
get_format_items(format, right_justify, add_sign, fill_char,
|
||||
string_length, point_precision, format_type);
|
||||
if (format_type.all = "b") or (format_type.all = "d") or
|
||||
(format_type.all = "X") or (format_type.all = "x") then
|
||||
logic_vector(1) := value;
|
||||
return(sprintf(format, std_ulogic_vector(logic_vector)));
|
||||
else
|
||||
return("Not a std_logic format: '" & format_type.all & "'");
|
||||
end if;
|
||||
end sprintf;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- std_ulogic_vector
|
||||
------------------------------------------------------------------------------
|
||||
function sprintf(format : string; value : std_ulogic_vector) return string is
|
||||
variable right_justify : boolean;
|
||||
variable add_sign : boolean;
|
||||
variable fill_char : character;
|
||||
variable bit_string_length : natural;
|
||||
variable point_precision : natural;
|
||||
variable format_type : line;
|
||||
begin
|
||||
get_format_items(format, right_justify, add_sign, fill_char,
|
||||
bit_string_length, point_precision, format_type);
|
||||
if format_type.all = "b" then
|
||||
return(pad(sprintf_b(value), bit_string_length, fill_char, right_justify));
|
||||
elsif format_type.all = "d" then
|
||||
return(sprintf_d(right_justify, add_sign, fill_char, bit_string_length, to_integer(unsigned(value))));
|
||||
elsif (format_type.all = "X") or (format_type.all = "x") then
|
||||
if format_type.all = "X" then
|
||||
return(pad(sprintf_X(true, value), bit_string_length, fill_char, right_justify));
|
||||
else
|
||||
return(lc(pad(sprintf_X(true, value), bit_string_length, fill_char, right_justify)));
|
||||
end if;
|
||||
else
|
||||
return("Not a std_ulogic_vector format: '" & format_type.all & "'");
|
||||
end if;
|
||||
end sprintf;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- std_logic_vector
|
||||
------------------------------------------------------------------------------
|
||||
function sprintf(format : string; value : std_logic_vector) return string is
|
||||
variable right_justify : boolean;
|
||||
variable add_sign : boolean;
|
||||
variable fill_char : character;
|
||||
variable string_length : natural;
|
||||
variable point_precision : natural;
|
||||
variable format_type : line;
|
||||
begin
|
||||
get_format_items(format, right_justify, add_sign, fill_char,
|
||||
string_length, point_precision, format_type);
|
||||
if (format_type.all = "b") or (format_type.all = "d") or
|
||||
(format_type.all = "X") or (format_type.all = "x") then
|
||||
return(sprintf(format, std_ulogic_vector(value)));
|
||||
else
|
||||
return("Not a std_logic_vector format: '" & format_type.all & "'");
|
||||
end if;
|
||||
end sprintf;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- unsigned
|
||||
------------------------------------------------------------------------------
|
||||
function sprintf(format : string; value : unsigned) return string is
|
||||
variable right_justify : boolean;
|
||||
variable add_sign : boolean;
|
||||
variable fill_char : character;
|
||||
variable string_length : natural;
|
||||
variable point_precision : natural;
|
||||
variable format_type : line;
|
||||
begin
|
||||
get_format_items(format, right_justify, add_sign, fill_char,
|
||||
string_length, point_precision, format_type);
|
||||
if (format_type.all = "b") or (format_type.all = "d") or
|
||||
(format_type.all = "X") or (format_type.all = "x") then
|
||||
return(sprintf(format, std_ulogic_vector(value)));
|
||||
else
|
||||
return("Not an unsigned format: '" & format_type.all & "'");
|
||||
end if;
|
||||
end sprintf;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- signed
|
||||
------------------------------------------------------------------------------
|
||||
function sprintf(format : string; value : signed) return string is
|
||||
variable right_justify : boolean;
|
||||
variable add_sign : boolean;
|
||||
variable fill_char : character;
|
||||
variable bit_string_length : natural;
|
||||
variable point_precision : natural;
|
||||
variable format_type : line;
|
||||
begin
|
||||
get_format_items(format, right_justify, add_sign, fill_char,
|
||||
bit_string_length, point_precision, format_type);
|
||||
if (fill_char = '0') and (value(value'left) = '1') then
|
||||
fill_char := '1';
|
||||
end if;
|
||||
if format_type.all = "b" then
|
||||
return(pad(sprintf_b(std_ulogic_vector(value)), bit_string_length, fill_char, right_justify));
|
||||
elsif format_type.all = "d" then
|
||||
return(sprintf_d(right_justify, add_sign, fill_char, bit_string_length, to_integer(signed(value))));
|
||||
elsif (format_type.all = "X") or (format_type.all = "x") then
|
||||
if fill_char = '1' then
|
||||
fill_char := 'F';
|
||||
end if;
|
||||
if format_type.all = "X" then
|
||||
return(pad(sprintf_X(true, std_ulogic_vector(value)), bit_string_length, fill_char, right_justify));
|
||||
else
|
||||
return(lc(pad(sprintf_X(true, std_ulogic_vector(value)), bit_string_length, fill_char, right_justify)));
|
||||
end if;
|
||||
else
|
||||
return("Not a signed format: '" & format_type.all & "'");
|
||||
end if;
|
||||
end sprintf;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- time
|
||||
------------------------------------------------------------------------------
|
||||
function sprintf(format : string; value : time) return string is
|
||||
variable right_justify : boolean;
|
||||
variable add_sign : boolean;
|
||||
variable fill_char : character;
|
||||
variable string_length : natural;
|
||||
variable point_precision : natural;
|
||||
variable format_type : line;
|
||||
variable scaling : real;
|
||||
variable base_time : time;
|
||||
variable unit : string(1 to 3);
|
||||
begin
|
||||
get_format_items(format, right_justify, add_sign, fill_char,
|
||||
string_length, point_precision, format_type);
|
||||
if format_type.all(format_type.all'left) = 't' then
|
||||
scaling := 10.0**point_precision;
|
||||
if format_type.all = "tp" then
|
||||
base_time := 1 ps;
|
||||
unit := " ps";
|
||||
elsif format_type.all = "tn" then
|
||||
base_time := 1 ns;
|
||||
unit := " ns";
|
||||
elsif format_type.all = "tu" then
|
||||
base_time := 1 us;
|
||||
unit := " us";
|
||||
elsif format_type.all = "tm" then
|
||||
base_time := 1 ms;
|
||||
unit := " ms";
|
||||
elsif format_type.all = "ts" then
|
||||
base_time := 1 sec;
|
||||
unit := " s.";
|
||||
else
|
||||
return("Undefined time format: '" & format_type.all & "'");
|
||||
end if;
|
||||
if point_precision = 0 then
|
||||
return(sprintf_d(right_justify, add_sign, fill_char,
|
||||
string_length, value/base_time) & unit);
|
||||
else
|
||||
return(sprintf_f(right_justify, add_sign, fill_char, string_length,
|
||||
point_precision, real(scaling*value/base_time)/scaling) & unit);
|
||||
end if;
|
||||
else
|
||||
return("Not a time format: '" & format_type.all & "'");
|
||||
end if;
|
||||
end sprintf;
|
||||
|
||||
|
||||
--============================================================================
|
||||
-- formatted string input
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- read a nibble out of a character
|
||||
------------------------------------------------------------------------------
|
||||
function sscanf(value : character) return natural is
|
||||
begin
|
||||
if (value >= '0') and (value <= '9') then
|
||||
return(character'pos(value) - character'pos('0'));
|
||||
elsif (value >= 'a') and (value <= 'f') then
|
||||
return(character'pos(value) - character'pos('a') + 10);
|
||||
elsif (value >= 'A') and (value <= 'F') then
|
||||
return(character'pos(value) - character'pos('A') + 10);
|
||||
else
|
||||
return(0);
|
||||
end if;
|
||||
end sscanf;
|
||||
|
||||
function sscanf(value : character) return nibbleUnsignedType is
|
||||
begin
|
||||
return(to_unsigned(sscanf(value), nibbleUnsignedType'length));
|
||||
end sscanf;
|
||||
|
||||
function sscanf(value : character) return nibbleUlogicType is
|
||||
variable unsigned_value : nibbleUnsignedType;
|
||||
begin
|
||||
unsigned_value := sscanf(value);
|
||||
return(std_ulogic_vector(unsigned_value));
|
||||
end sscanf;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- read an binary word out of a string
|
||||
------------------------------------------------------------------------------
|
||||
function sscanf(value : string) return natural is
|
||||
variable integer_value : natural;
|
||||
begin
|
||||
integer_value := 0;
|
||||
for index in value'left to value'right loop
|
||||
integer_value := integer_value*16 + sscanf(value(index));
|
||||
end loop;
|
||||
return(integer_value);
|
||||
end;
|
||||
|
||||
function sscanf(value : string) return unsigned is
|
||||
variable unsigned_value : unsigned(4*value'length-1 downto 0);
|
||||
begin
|
||||
unsigned_value := to_unsigned(0,unsigned_value'length);
|
||||
for index in value'left to value'right loop
|
||||
unsigned_value := shift_left(unsigned_value,4) + to_unsigned(sscanf(value(index)),4);
|
||||
end loop;
|
||||
return(unsigned_value);
|
||||
end;
|
||||
|
||||
function sscanf(value : string) return std_ulogic_vector is
|
||||
variable unsigned_value : unsigned(4*value'length-1 downto 0);
|
||||
begin
|
||||
unsigned_value := sscanf(value);
|
||||
return(std_ulogic_vector(unsigned_value));
|
||||
end;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- read time from a string
|
||||
-- time can be formated as follows:
|
||||
-- "1ps" or "1 ps" or " 1 ps " or " 1ps"
|
||||
-- possible time units are: hr, min, sec, ms, us, ns, ps, fs
|
||||
------------------------------------------------------------------------------
|
||||
procedure sscanf(
|
||||
value : inout line;
|
||||
time_val : out time
|
||||
) is
|
||||
variable time_line : line := value;
|
||||
variable time_base : string(1 to 3);
|
||||
variable time_value : integer;
|
||||
variable time_int : time;
|
||||
begin
|
||||
-- remove all spaces and tabs
|
||||
rm_all_separators(time_line);
|
||||
|
||||
-- strip time base (3 last characters)
|
||||
time_base := time_line(time_line'right-2 to time_line'right);
|
||||
|
||||
-- separate time value and base
|
||||
if time_base(2 to 3) = "hr" then
|
||||
time_int := 1 hr;
|
||||
time_value := integer'value(time_line(time_line'left to time_line'right -2));
|
||||
elsif time_base = "min" then
|
||||
time_int := 1 min;
|
||||
time_value := integer'value(time_line(time_line'left to time_line'right -3));
|
||||
elsif time_base = "sec" then
|
||||
time_int := 1 sec;
|
||||
time_value := integer'value(time_line(time_line'left to time_line'right -3));
|
||||
elsif time_base(2 to 3) = "ms" then
|
||||
time_int := 1 ms;
|
||||
time_value := integer'value(time_line(time_line'left to time_line'right -2));
|
||||
elsif time_base(2 to 3) = "us" then
|
||||
time_int := 1 us;
|
||||
time_value := integer'value(time_line(time_line'left to time_line'right -2));
|
||||
elsif time_base(2 to 3) = "ns" then
|
||||
time_int := 1 ns;
|
||||
time_value := integer'value(time_line(time_line'left to time_line'right -2));
|
||||
elsif time_base(2 to 3) = "ps" then
|
||||
time_int := 1 ps;
|
||||
time_value := integer'value(time_line(time_line'left to time_line'right -2));
|
||||
elsif time_base(2 to 3) = "fs" then
|
||||
time_int := 1 fs;
|
||||
time_value := integer'value(time_line(time_line'left to time_line'right -2));
|
||||
else
|
||||
time_int := 0 ps;
|
||||
time_value := 1;
|
||||
end if;
|
||||
|
||||
-- build time from value and base
|
||||
time_val := time_int * time_value;
|
||||
|
||||
end;
|
||||
|
||||
function sscanf(value : string) return time is
|
||||
variable value_line : line;
|
||||
variable time_val : time;
|
||||
begin
|
||||
value_line := new string'(value);
|
||||
sscanf(value_line, time_val);
|
||||
return(time_val);
|
||||
end;
|
||||
|
||||
END testUtils;
|
102
Libs/Common_test/hdl/testUtils_tb_test.vhd
Normal file
102
Libs/Common_test/hdl/testUtils_tb_test.vhd
Normal file
@ -0,0 +1,102 @@
|
||||
LIBRARY std;
|
||||
USE std.textio.all;
|
||||
LIBRARY Common_test;
|
||||
USE Common_test.testUtils.all;
|
||||
|
||||
ARCHITECTURE test OF testUtils_tb IS
|
||||
BEGIN
|
||||
|
||||
process
|
||||
variable test_line, result_line : LINE;
|
||||
begin
|
||||
|
||||
print("Integers, right justified");
|
||||
print(" |" & sprintf("%6d", 12) & "| 12|");
|
||||
print(" |" & sprintf("%06d", 12) & "|000012|");
|
||||
print(" |" & sprintf("%+6d", 12) & "| +12|");
|
||||
print(" |" & sprintf("%+06d", 12) & "|+00012|");
|
||||
print(" |" & sprintf("%6d", -12) & "| -12|");
|
||||
print(" |" & sprintf("%06d", -12) & "|-00012|");
|
||||
print("Integers, left justified");
|
||||
print(" |" & sprintf("%-6d", 12) & "|12 |");
|
||||
print(" |" & sprintf("%-06d", 12) & "|12 |");
|
||||
print(" |" & sprintf("%-+6d", 12) & "|+12 |");
|
||||
print(" |" & sprintf("%-+06d", 12) & "|+12 |");
|
||||
print(" |" & sprintf("%-6d", -12) & "|-12 |");
|
||||
print(" |" & sprintf("%-06d", -12) & "|-12 |");
|
||||
print("Integers, others");
|
||||
print(" |" & sprintf("%d", 12) & "|12|");
|
||||
print(" |" & sprintf("%6tu", 12) & "|");
|
||||
print(" |" & sprintf("%6d", 123456) & "|123456|");
|
||||
print(" |" & sprintf("%6d", 12345678) & "|#45678|");
|
||||
print(" |" & sprintf("%f", 12) & "|12.000000|");
|
||||
print(" |" & sprintf("%10f", 12) & "| 12.000000|");
|
||||
print(" |" & sprintf("%8.3f", 12) & "| 12.000|");
|
||||
print(" |" & sprintf("%b", 12) & "|00001100|");
|
||||
print(" |" & sprintf("%4b", 12) & "|1100|");
|
||||
print(" |" & sprintf("%6b", 12) & "|001100|");
|
||||
print(" |" & sprintf("%X", 12) & "|0000000C|");
|
||||
print(" |" & sprintf("%4x", 12) & "|000c|");
|
||||
print(" |" & sprintf("%2X", 12) & "|0C|");
|
||||
|
||||
print(cr & "Reals, integer rounding");
|
||||
print(" |" & sprintf("%6d", 1.3) & "| 1|");
|
||||
print(" |" & sprintf("%6d", 1.5) & "| 2|");
|
||||
print(" |" & sprintf("%6d", 1.7) & "| 2|");
|
||||
print("Reals, right justified");
|
||||
print(" |" & sprintf("%8.3f", 1.03) & "| 1.030|");
|
||||
print(" |" & sprintf("%8.3f", 1.07) & "| 1.070|");
|
||||
print(" |" & sprintf("%08.3f", 1.03) & "|0001.030|");
|
||||
print(" |" & sprintf("%+08.3f", 1.03) & "|+001.030|");
|
||||
print(" |" & sprintf("%8.3f", -1.03) & "| -1.030|");
|
||||
print(" |" & sprintf("%8.3f", -1.07) & "| -1.070|");
|
||||
print("Reals, left justified");
|
||||
print(" |" & sprintf("%-8.3f", 1.3) & "|1.300 |");
|
||||
print(" |" & sprintf("%-8.3f", 1.7) & "|1.700 |");
|
||||
print(" |" & sprintf("%-08.3f", 1.3) & "|1.300 |");
|
||||
print(" |" & sprintf("%-+08.3f", 1.3) & "|+1.300 |");
|
||||
print(" |" & sprintf("%-8.3f", -1.3) & "|-1.300 |");
|
||||
print(" |" & sprintf("%-8.3f", -1.7) & "|-1.700 |");
|
||||
|
||||
print(cr & "Logic values");
|
||||
print(" |" & sprintf("%b", '0') & "|0|");
|
||||
print(" |" & sprintf("%3b", '1') & "| 1|");
|
||||
print(" |" & sprintf("%-3d", '0') & "|0 |");
|
||||
print(" |" & sprintf("%3X", '1') & "| 1|");
|
||||
|
||||
print(cr & "Logic vectors, binary");
|
||||
print(" |" & sprintf("%b", std_ulogic_vector'("1100")) & "|1100|");
|
||||
print(" |" & sprintf("%3b", std_logic_vector'("1100")) & "|#00|");
|
||||
print(" |" & sprintf("%4b", unsigned'("1100")) & "|1100|");
|
||||
print(" |" & sprintf("%8b", signed'("1100")) & "| 1100|");
|
||||
print(" |" & sprintf("%-8b", signed'("1100")) & "|1100 |");
|
||||
print(" |" & sprintf("%08b", unsigned'("1100")) & "|00001100|");
|
||||
print(" |" & sprintf("%08b", signed'("1100")) & "|11111100|");
|
||||
print("Logic vectors, hexadecimal");
|
||||
print(" |" & sprintf("%X", std_ulogic_vector'("1100101011111110")) & "|CAFE|");
|
||||
print(" |" & sprintf("%3X", std_logic_vector'("1100101011111110")) & "|#FE|");
|
||||
print(" |" & sprintf("%4x", unsigned'("1100101011111110")) & "|cafe|");
|
||||
print(" |" & sprintf("%8X", signed'("1100101011111110")) & "| CAFE|");
|
||||
print(" |" & sprintf("%02X", unsigned'("1100")) & "|0C|");
|
||||
print(" |" & sprintf("%02X", signed'("1100")) & "|FC|");
|
||||
print("Logic vectors, decimal");
|
||||
print(" |" & sprintf("%d", std_ulogic_vector'("1100")) & "|12|");
|
||||
print(" |" & sprintf("%d", unsigned'("1100")) & "|12|");
|
||||
print(" |" & sprintf("%d", signed'("1100")) & "|-4|");
|
||||
print("Logic vectors, others");
|
||||
print(" |" & sprintf("%8tu", std_ulogic_vector'("1100")) & "|");
|
||||
|
||||
print(cr & "Time");
|
||||
print(" |" & sprintf("%9tu", 1.3 us) & "| 1 us|");
|
||||
print(" |" & sprintf("%9.3tu", 1.3 us) & "| 1.300 us|");
|
||||
print(" |" & sprintf("%10tu", 1.3 us) & "| 1 us|");
|
||||
|
||||
print(cr & "Lines");
|
||||
test_line := new string'("Hello brave new world!");
|
||||
read_first(test_line, result_line);
|
||||
print(" |" & result_line.all & "¦"& test_line.all & "|Hello¦brave new world!|");
|
||||
|
||||
wait;
|
||||
end process;
|
||||
|
||||
END ARCHITECTURE test;
|
56
Libs/Common_test/hdl/toggler_tester_test.vhd
Normal file
56
Libs/Common_test/hdl/toggler_tester_test.vhd
Normal file
@ -0,0 +1,56 @@
|
||||
ARCHITECTURE test OF toggler_tester IS
|
||||
|
||||
constant clockFrequency : real := 66.0E6;
|
||||
constant clockPeriod : time := 1.0/clockFrequency * 1 sec;
|
||||
signal clock_int : std_ulogic := '1';
|
||||
|
||||
BEGIN
|
||||
------------------------------------------------------------------------------
|
||||
-- reset and clock
|
||||
reset <= '1', '0' after 3*clockPeriod;
|
||||
clock_int <= not clock_int after clockPeriod/2;
|
||||
clock <= transport clock_int after clockPeriod*9/10;
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- input signal
|
||||
process
|
||||
begin
|
||||
input <= '0';
|
||||
wait for 10*clockPeriod;
|
||||
-- transition 0 to 1
|
||||
input <= '1',
|
||||
'0' after 1*clockPeriod,
|
||||
'1' after 3*clockPeriod,
|
||||
'0' after 5*clockPeriod,
|
||||
'1' after 6*clockPeriod,
|
||||
'0' after 8*clockPeriod,
|
||||
'1' after 10*clockPeriod;
|
||||
wait for 50*clockPeriod;
|
||||
-- transition 1 to 0
|
||||
input <= '0',
|
||||
'1' after 1*clockPeriod,
|
||||
'0' after 3*clockPeriod,
|
||||
'1' after 5*clockPeriod,
|
||||
'0' after 6*clockPeriod,
|
||||
'1' after 8*clockPeriod,
|
||||
'0' after 10*clockPeriod;
|
||||
wait for 50*clockPeriod;
|
||||
-- short 1 pulse
|
||||
input <= '1',
|
||||
'0' after 1*clockPeriod,
|
||||
'1' after 3*clockPeriod,
|
||||
'0' after 5*clockPeriod,
|
||||
'1' after 6*clockPeriod,
|
||||
'0' after 8*clockPeriod;
|
||||
wait for 50*clockPeriod;
|
||||
-- further toggle commands
|
||||
input <= '1', '0' after clockPeriod;
|
||||
wait for 50*clockPeriod;
|
||||
input <= '1', '0' after clockPeriod;
|
||||
wait for 50*clockPeriod;
|
||||
-- short 1 pulse
|
||||
-- end of simulation
|
||||
wait;
|
||||
end process;
|
||||
|
||||
END ARCHITECTURE test;
|
@ -0,0 +1 @@
|
||||
DIALECT atom VHDL_2008
|
@ -0,0 +1,4 @@
|
||||
INCLUDE list {
|
||||
DEFAULT atom 1
|
||||
}
|
||||
DIALECT atom VHDL_2008
|
@ -0,0 +1,4 @@
|
||||
DIALECT atom VHDL_2008
|
||||
INCLUDE list {
|
||||
DEFAULT atom 1
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
INCLUDE list {
|
||||
DEFAULT atom 1
|
||||
}
|
||||
DIALECT atom VHDL_2008
|
@ -0,0 +1 @@
|
||||
DIALECT atom VHDL_2008
|
@ -0,0 +1 @@
|
||||
DIALECT atom VHDL_93
|
1
Libs/Common_test/hds/.hdlsidedata/_rotarytounsigned_tb_entity.vhd._fpf
Executable file
1
Libs/Common_test/hds/.hdlsidedata/_rotarytounsigned_tb_entity.vhd._fpf
Executable file
@ -0,0 +1 @@
|
||||
DIALECT atom VHDL_2008
|
1
Libs/Common_test/hds/.hdlsidedata/_rotarytounsigned_tb_struct.vhd._fpf
Executable file
1
Libs/Common_test/hds/.hdlsidedata/_rotarytounsigned_tb_struct.vhd._fpf
Executable file
@ -0,0 +1 @@
|
||||
DIALECT atom VHDL_2008
|
@ -0,0 +1 @@
|
||||
DIALECT atom VHDL_2008
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user