URL
https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk
Subversion Repositories open8_urisc
[/] [open8_urisc/] [trunk/] [VHDL/] [o8_scale_conv.vhd] - Rev 329
Go to most recent revision | Compare with Previous | Blame | View Log
-- Copyright (c)2023 Jeremy Seth Henry -- All rights reserved. -- -- Redistribution and use in source and binary forms, with or without -- modification, are permitted provided that the following conditions are met: -- * Redistributions of source code must retain the above copyright -- notice, this list of conditions and the following disclaimer. -- * Redistributions in binary form must reproduce the above copyright -- notice, this list of conditions and the following disclaimer in the -- documentation and/or other materials provided with the distribution, -- where applicable (as part of a user interface, debugging port, etc.) -- -- THIS SOFTWARE IS PROVIDED BY JEREMY SETH HENRY ``AS IS'' AND ANY -- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -- DISCLAIMED. IN NO EVENT SHALL JEREMY SETH HENRY BE LIABLE FOR ANY -- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -- -- VHDL units : o8_scale_conv -- Description: Performs the operation ACC = [(A*B)/C] + D, returning a 33-bit -- value. Optionally converts this value into packed BCD format. -- -- Note1: Operands A,B are 16-bit values. The output from this step is a 32-bit -- value, which can be divided by Operand C, with the result added to -- Operand D. Both operand C and D are 32-bit values. -- Note2: If the operation type is '1', or SIGNED, then operand A,B, and D -- will be treated as SIGNED values, while operand C remains UNSIGNED -- If the operation type is '0', or UNSIGNED, all operands will be -- treated as UNSIGNED values. -- Note3: Setting Operand C to 0 or 1 will skip the division step. This -- resolves the issue of divide by 0, as 0 will be treated as 1, as -- well as saving time if the division isn't required. -- -- Register Map: -- Offset Bitfield Description Read/Write -- 0x00 AAAAAAAA Operand A, Lower Byte (RW) -- 0x01 AAAAAAAA Operand A, Upper Byte (RW) -- 0x02 AAAAAAAA Operand B, Lower Byte (RW) -- 0x03 AAAAAAAA Operand B, Upper Byte (RW) -- 0x04 AAAAAAAA Operand C, Byte 0 (RW) -- 0x05 AAAAAAAA Operand C, Byte 1 (RW) -- 0x06 AAAAAAAA Operand C, Byte 2 (RW) -- 0x07 AAAAAAAA Operand C, Byte 3 (RW) -- 0x08 AAAAAAAA Operand D, Byte 0 (RW) -- 0x09 AAAAAAAA Operand D, Byte 1 (RW) -- 0x0A AAAAAAAA Operand D, Byte 2 (RW) -- 0x0B AAAAAAAA Operand D, Byte 3 (RW) -- -- 0x10 AAAAAAAA Accumulator, Byte 0 (R0) -- 0x11 AAAAAAAA Accumulator, Byte 1 (R0) -- 0x12 AAAAAAAA Accumulator, Byte 2 (R0) -- 0x13 AAAAAAAA Accumulator, Byte 3 (R0) -- 0x14 A------- Accumulator, Sign / Bit 32 (R0) -- -- 0x18 AAAAAAAA BCD Data, Digits 1,0 (RO) -- 0x19 AAAAAAAA BCD Data, Digits 3,2 (RO) -- 0x1A AAAAAAAA BCD Data, Digits 5,4 (RO) -- 0x1B AAAAAAAA BCD Data, Digits 7,6 (RO) -- 0x1C AAAAAAAA BCD Data, Digits 9,8 (RO) -- 0x1D A------- BCD Data, Sign [pos (0), neg (1)] (RO) -- -- 0x1F C-----BA Control/Status (RW) -- A = Operation Type: -- Unsigned (0) / Signed (1) -- B = BCD conversion (if set) (WR)* -- BCD result valid if set (RD) -- C = Conversion Status (1 = busy) -- -- Note4: Setting bit 1 TRUE will enable the packed BCD conversion system -- at the cost of ~3.5uS per conversion. If the most recent result -- was converted, reading this bit will return a '1' to indicate -- that the data is "fresh", or matches the raw result data. -- Setting this bit FALSE will allow a new math operation to occur -- WITHOUT altering the last BCD conversion, but will set this bit to -- 0 on read to indicate that the BCD value is "stale", or no longer -- matches the raw result data. -- -- Revision History -- Author Date Change ------------------ -------- --------------------------------------------------- -- Seth Henry 04/10/23 Initial Design library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_signed.all; use ieee.std_logic_arith.all; use ieee.std_logic_misc.all; library work; use work.open8_pkg.all; use work.open8_cfg.all; entity o8_scale_conv is generic( Address : ADDRESS_TYPE ); port( -- Bus IF Interface Open8_Bus : in OPEN8_BUS_TYPE; Write_Qual : in std_logic; Rd_Data : out DATA_TYPE; Interrupt : out std_logic ); end entity; architecture behave of o8_scale_conv is -- Bus Interface Signals alias Clock is Open8_Bus.Clock; alias Reset is Open8_Bus.Reset; alias uSec_Tick is Open8_Bus.uSec_Tick; constant User_Addr : std_logic_vector(15 downto 5) := Address(15 downto 5); alias Comp_Addr is Open8_Bus.Address(15 downto 5); signal Addr_Match : std_logic := '0'; alias Reg_Sel_d is Open8_Bus.Address(4 downto 0); signal Reg_Sel_q : std_logic_vector(4 downto 0) := (others => '0'); signal Wr_En_d : std_logic := '0'; signal Wr_En_q : std_logic := '0'; alias Wr_Data_d is Open8_Bus.Wr_Data; signal Wr_Data_q : DATA_TYPE := x"00"; signal Rd_En_d : std_logic := '0'; signal Rd_En_q : std_logic := '0'; -- Operands A, B, and C are 16-bit with sign-extension, or 17-bit values constant OPER_ABC_WIDTH : integer := 17; signal OperandA : signed(OPER_ABC_WIDTH - 1 downto 0) := (others => '0'); alias OperandA_LB is OperandA(7 downto 0); alias OperandA_UB is OperandA(15 downto 8); alias OperandA_S is OperandA(15); alias OperandA_SX is OperandA(OPER_ABC_WIDTH - 1 downto 16); signal OperandB : signed(OPER_ABC_WIDTH - 1 downto 0) := (others => '0'); alias OperandB_LB is OperandB(7 downto 0); alias OperandB_UB is OperandB(15 downto 8); alias OperandB_S is OperandB(15); alias OperandB_SX is OperandB(OPER_ABC_WIDTH - 1 downto 16); -- The product will, by definition, be twice as wide as the input operands constant MULT_WIDTH : integer := 2*OPER_ABC_WIDTH; signal Product_AB : signed(MULT_WIDTH - 1 downto 0) := (others => '0'); -- The divider only needs a single bit for sign extension, so drop one -- bit from the multiplier width constant DIVIDER_WIDTH : integer := MULT_WIDTH - 1; alias Operand_AB is Product_AB(DIVIDER_WIDTH - 1 downto 0); signal OperandC : signed(DIVIDER_WIDTH - 1 downto 0) := (others => '0'); alias OperandC_B0 is OperandC(7 downto 0); alias OperandC_B1 is OperandC(15 downto 8); alias OperandC_B2 is OperandC(23 downto 16); alias OperandC_B3 is OperandC(31 downto 24); alias OperandC_SX is OperandC(DIVIDER_WIDTH - 1 downto 32); signal OperandABC : signed(DIVIDER_WIDTH - 1 downto 0) := (others => '0'); signal OperandD : signed(DIVIDER_WIDTH - 1 downto 0) := (others => '0'); alias OperandD_B0 is OperandD(7 downto 0); alias OperandD_B1 is OperandD(15 downto 8); alias OperandD_B2 is OperandD(23 downto 16); alias OperandD_B3 is OperandD(31 downto 24); alias OperandD_S is OperandD(31); alias OperandD_SX is OperandD(DIVIDER_WIDTH - 1 downto 32); signal Accumulator : signed(DIVIDER_WIDTH - 1 downto 0) := (others => '0'); alias RAW_Data_B0 is Accumulator(7 downto 0); alias RAW_Data_B1 is Accumulator(15 downto 8); alias RAW_Data_B2 is Accumulator(23 downto 16); alias RAW_Data_B3 is Accumulator(31 downto 24); alias RAW_Sign_MSB is Accumulator(32); -- Conversion control signals type CONV_STATES is ( IDLE, MULT_WAIT, DIV_START, DIV_WAIT, DIV_SKIP, ACCUM_WAIT, DAA_INIT, DAA_NEGATE, DAA_STEP1, DAA_WAIT1, DAA_STEP2, DAA_WAIT2, DAA_STEP3, DAA_WAIT3, DAA_STEP4, DAA_WAIT4, DAA_STEP5, DAA_WAIT5, DAA_STEP6, DAA_WAIT6, DAA_STEP7, DAA_WAIT7, DAA_STEP8, DAA_WAIT8, DAA_STEP9, DAA_WAIT9, DAA_DONE ); signal Conv_State : CONV_STATES := IDLE; signal CNV_En : std_logic := '0'; signal DAA_En : std_logic := '0'; signal CNV_Busy : std_logic := '0'; signal CNV_Mode : std_logic := '0'; constant CNV_SIGNED : std_logic := '1'; constant CNV_UNSIGNED : std_logic := '0'; signal CNV_Done : std_logic := '0'; -- Decimal adjust / BCD conversion signals signal DAA_Valid : std_logic := '0'; constant DAA_ST1_DIV : std_logic_vector(DIVIDER_WIDTH - 1 downto 0) := conv_std_logic_vector(1000000000,DIVIDER_WIDTH); constant DAA_ST2_DIV : std_logic_vector(DIVIDER_WIDTH - 1 downto 0) := conv_std_logic_vector(100000000,DIVIDER_WIDTH); constant DAA_ST3_DIV : std_logic_vector(DIVIDER_WIDTH - 1 downto 0) := conv_std_logic_vector(10000000,DIVIDER_WIDTH); constant DAA_ST4_DIV : std_logic_vector(DIVIDER_WIDTH - 1 downto 0) := conv_std_logic_vector(1000000,DIVIDER_WIDTH); constant DAA_ST5_DIV : std_logic_vector(DIVIDER_WIDTH - 1 downto 0) := conv_std_logic_vector(100000,DIVIDER_WIDTH); constant DAA_ST6_DIV : std_logic_vector(DIVIDER_WIDTH - 1 downto 0) := conv_std_logic_vector(10000,DIVIDER_WIDTH); constant DAA_ST7_DIV : std_logic_vector(DIVIDER_WIDTH - 1 downto 0) := conv_std_logic_vector(1000,DIVIDER_WIDTH); constant DAA_ST8_DIV : std_logic_vector(DIVIDER_WIDTH - 1 downto 0) := conv_std_logic_vector(100,DIVIDER_WIDTH); constant DAA_ST9_DIV : std_logic_vector(DIVIDER_WIDTH - 1 downto 0) := conv_std_logic_vector(10,DIVIDER_WIDTH); signal DAA_Next : std_logic_vector(DIVIDER_WIDTH - 1 downto 0) := (others => '0'); signal DAA_Sign : std_logic := '0'; signal DAA_Buffer : std_logic_vector(39 downto 0) := (others => '0'); alias DAA_Data_B0 is DAA_Buffer(7 downto 0); alias DAA_Data_B1 is DAA_Buffer(15 downto 8); alias DAA_Data_B2 is DAA_Buffer(23 downto 16); alias DAA_Data_B3 is DAA_Buffer(31 downto 24); alias DAA_Data_B4 is DAA_Buffer(39 downto 32); alias DAA_Digit_0 is DAA_Buffer( 3 downto 0); alias DAA_Digit_1 is DAA_Buffer( 7 downto 4); alias DAA_Digit_2 is DAA_Buffer(11 downto 8); alias DAA_Digit_3 is DAA_Buffer(15 downto 12); alias DAA_Digit_4 is DAA_Buffer(19 downto 16); alias DAA_Digit_5 is DAA_Buffer(23 downto 20); alias DAA_Digit_6 is DAA_Buffer(27 downto 24); alias DAA_Digit_7 is DAA_Buffer(31 downto 28); alias DAA_Digit_8 is DAA_Buffer(35 downto 32); alias DAA_Digit_9 is DAA_Buffer(39 downto 36); -- Integer divide unit signals signal Div_Enable : std_logic := '0'; signal Div_Busy : std_logic := '0'; signal Dividend : std_logic_vector(DIVIDER_WIDTH - 1 downto 0) := (others => '0'); signal Divisor : std_logic_vector(DIVIDER_WIDTH - 1 downto 0) := (others => '0'); signal Quotient : std_logic_vector(DIVIDER_WIDTH - 1 downto 0) := (others => '0'); signal Remainder : std_logic_vector(DIVIDER_WIDTH - 1 downto 0) := (others => '0'); begin Addr_Match <= '1' when Comp_Addr = User_Addr else '0'; Wr_En_d <= Addr_Match and Open8_Bus.Wr_En and Write_Qual; Rd_En_d <= Addr_Match and Open8_Bus.Rd_En; reg_proc: process( Clock, Reset ) begin if( Reset = Reset_Level )then Reg_Sel_q <= (others => '0'); Wr_En_q <= '0'; Wr_Data_q <= x"00"; Rd_En_q <= '0'; Rd_Data <= OPEN8_NULLBUS; OperandA <= (others => '0'); OperandB <= (others => '0'); OperandC <= (others => '0'); OperandD <= (others => '0'); CNV_En <= '0'; DAA_En <= '0'; CNV_Mode <= '0'; CNV_Busy <= '0'; Interrupt <= '0'; elsif( rising_edge(Clock) )then Reg_Sel_q <= Reg_Sel_d; Wr_En_q <= Wr_En_d; Wr_Data_q <= Wr_Data_d; CNV_En <= '0'; if( Wr_En_q = '1' )then case( Reg_Sel_q )is when "00000" => OperandA_LB <= signed(Wr_Data_q); when "00001" => OperandA_UB <= signed(Wr_Data_q); when "00010" => OperandB_LB <= signed(Wr_Data_q); when "00011" => OperandB_UB <= signed(Wr_Data_q); when "00100" => OperandC_B0 <= signed(Wr_Data_q); when "00101" => OperandC_B1 <= signed(Wr_Data_q); when "00110" => OperandC_B2 <= signed(Wr_Data_q); when "00111" => OperandC_B3 <= signed(Wr_Data_q); when "01000" => OperandD_B0 <= signed(Wr_Data_q); when "01001" => OperandD_B1 <= signed(Wr_Data_q); when "01010" => OperandD_B2 <= signed(Wr_Data_q); when "01011" => OperandD_B3 <= signed(Wr_Data_q); when "11111" => CNV_Mode <= Wr_Data_q(0); DAA_En <= Wr_Data_q(1); CNV_En <= '1'; CNV_Busy <= '1'; when others => null; end case; end if; Interrupt <= '0'; if( CNV_Done = '1' )then CNV_Busy <= '0'; Interrupt <= '1'; end if; OperandA_SX <= (others => '0'); OperandB_SX <= (others => '0'); OperandC_SX <= (others => '0'); OperandD_SX <= (others => '0'); if( CNV_Mode = CNV_SIGNED )then OperandA_SX <= (others => OperandA_S); OperandB_SX <= (others => OperandB_S); OperandD_SX <= (others => OperandD_S); end if; Rd_En_q <= Rd_En_d; Rd_Data <= OPEN8_NULLBUS; if( Rd_En_q = '1' )then case( Reg_Sel_q )is -- Input operands when "00000" => Rd_Data <= std_logic_vector(OperandA_LB); when "00001" => Rd_Data <= std_logic_vector(OperandA_UB); when "00010" => Rd_Data <= std_logic_vector(OperandB_LB); when "00011" => Rd_Data <= std_logic_vector(OperandB_UB); when "00100" => Rd_Data <= std_logic_vector(OperandC_B0); when "00101" => Rd_Data <= std_logic_vector(OperandC_B1); when "00110" => Rd_Data <= std_logic_vector(OperandC_B2); when "00111" => Rd_Data <= std_logic_vector(OperandC_B3); when "01000" => Rd_Data <= std_logic_vector(OperandD_B0); when "01001" => Rd_Data <= std_logic_vector(OperandD_B1); when "01010" => Rd_Data <= std_logic_vector(OperandD_B2); when "01011" => Rd_Data <= std_logic_vector(OperandD_B3); -- Raw results when "10000" => Rd_Data <= std_logic_vector(RAW_Data_B0); when "10001" => Rd_Data <= std_logic_vector(RAW_Data_B1); when "10010" => Rd_Data <= std_logic_vector(RAW_Data_B2); when "10011" => Rd_Data <= std_logic_vector(RAW_Data_B3); when "10100" => Rd_Data(7) <= RAW_Sign_MSB; -- BCD Conversion when "11000" => Rd_Data <= DAA_Data_B0; when "11001" => Rd_Data <= DAA_Data_B1; when "11010" => Rd_Data <= DAA_Data_B2; when "11011" => Rd_Data <= DAA_Data_B3; when "11100" => Rd_Data <= DAA_Data_B4; when "11101" => Rd_Data(7) <= DAA_Sign; -- Control/Status when "11111" => Rd_Data(0) <= CNV_Mode; Rd_Data(1) <= DAA_Valid; Rd_Data(7) <= CNV_Busy; when others => null; end case; end if; end if; end process; Conversion_FSM_proc: process( Clock, Reset ) begin if( Reset = Reset_Level )then Conv_State <= IDLE; Div_Enable <= '0'; Dividend <= (others => '0'); Divisor <= (others => '0'); OperandABC <= (others => '0'); Accumulator <= (others => '0'); DAA_Sign <= '0'; DAA_Buffer <= (others => '0'); DAA_Next <= (others => '0'); CNV_Done <= '0'; elsif( rising_edge(Clock) )then Div_Enable <= '0'; CNV_Done <= '0'; case Conv_State is when IDLE => if( CNV_En = '1' )then Conv_State <= MULT_WAIT; end if; when MULT_WAIT => -- Skip division if the operand is < 2 Conv_State <= DIV_SKIP; if( OperandC > 1 )then Conv_State <= DIV_START; end if; when DIV_START => Div_Enable <= '1'; Dividend <= std_logic_vector(Operand_AB); Divisor <= std_logic_vector(OperandC); if( Div_Busy = '1' )then Conv_State <= DIV_WAIT; end if; when DIV_WAIT => if( Div_Busy = '0' )then OperandABC <= signed(Quotient); Conv_State <= ACCUM_WAIT; end if; when DIV_SKIP => OperandABC <= Operand_AB; Conv_State <= ACCUM_WAIT; when ACCUM_WAIT => Conv_State <= DAA_INIT; if( DAA_En = '0' )then DAA_Valid <= '0'; CNV_Done <= '1'; Conv_State <= IDLE; end if; when DAA_INIT => DAA_Sign <= '0'; DAA_Next <= std_logic_vector(Accumulator); Conv_State <= DAA_STEP1; if( RAW_Sign_MSB = '1' and CNV_Mode = CNV_SIGNED )then Conv_State <= DAA_NEGATE; end if; when DAA_NEGATE => DAA_Sign <= '1'; DAA_Next <= (not DAA_Next) + 1; Conv_State <= DAA_STEP1; when DAA_STEP1 => Dividend <= DAA_Next; Divisor <= DAA_ST1_DIV; Div_Enable <= '1'; if( DIV_Busy = '1' )then Conv_State <= DAA_WAIT1; end if; when DAA_WAIT1 => if( DIV_Busy = '0' )then DAA_Digit_9 <= Quotient(3 downto 0); DAA_Next <= Remainder; Conv_State <= DAA_STEP2; end if; when DAA_STEP2 => Dividend <= DAA_Next; Divisor <= DAA_ST2_DIV; Div_Enable <= '1'; if( DIV_Busy = '1' )then Conv_State <= DAA_WAIT2; end if; when DAA_WAIT2 => if( DIV_Busy = '0' )then DAA_Digit_8 <= Quotient(3 downto 0); DAA_Next <= Remainder; Conv_State <= DAA_STEP3; end if; when DAA_STEP3 => Dividend <= DAA_Next; Divisor <= DAA_ST3_DIV; Div_Enable <= '1'; if( DIV_Busy = '1' )then Conv_State <= DAA_WAIT3; end if; when DAA_WAIT3 => if( DIV_Busy = '0' )then DAA_Digit_7 <= Quotient(3 downto 0); DAA_Next <= Remainder; Conv_State <= DAA_STEP4; end if; when DAA_STEP4 => Dividend <= DAA_Next; Divisor <= DAA_ST4_DIV; Div_Enable <= '1'; if( DIV_Busy = '1' )then Conv_State <= DAA_WAIT4; end if; when DAA_WAIT4 => if( DIV_Busy = '0' )then DAA_Digit_6 <= Quotient(3 downto 0); DAA_Next <= Remainder; Conv_State <= DAA_STEP5; end if; when DAA_STEP5 => Dividend <= DAA_Next; Divisor <= DAA_ST5_DIV; Div_Enable <= '1'; if( DIV_Busy = '1' )then Conv_State <= DAA_WAIT5; end if; when DAA_WAIT5 => if( DIV_Busy = '0' )then DAA_Digit_5 <= Quotient(3 downto 0); DAA_Next <= Remainder; Conv_State <= DAA_STEP6; end if; when DAA_STEP6 => Dividend <= DAA_Next; Divisor <= DAA_ST6_DIV; Div_Enable <= '1'; if( DIV_Busy = '1' )then Conv_State <= DAA_WAIT6; end if; when DAA_WAIT6 => if( DIV_Busy = '0' )then DAA_Digit_4 <= Quotient(3 downto 0); DAA_Next <= Remainder; Conv_State <= DAA_STEP7; end if; when DAA_STEP7 => Dividend <= DAA_Next; Divisor <= DAA_ST7_DIV; Div_Enable <= '1'; if( DIV_Busy = '1' )then Conv_State <= DAA_WAIT7; end if; when DAA_WAIT7 => if( DIV_Busy = '0' )then DAA_Digit_3 <= Quotient(3 downto 0); DAA_Next <= Remainder; Conv_State <= DAA_STEP8; end if; when DAA_STEP8 => Dividend <= DAA_Next; Divisor <= DAA_ST8_DIV; Div_Enable <= '1'; if( DIV_Busy = '1' )then Conv_State <= DAA_WAIT8; end if; when DAA_WAIT8 => if( DIV_Busy = '0' )then DAA_Digit_2 <= Quotient(3 downto 0); DAA_Next <= Remainder; Conv_State <= DAA_STEP9; end if; when DAA_STEP9 => Dividend <= DAA_Next; Divisor <= DAA_ST9_DIV; Div_Enable <= '1'; if( DIV_Busy = '1' )then Conv_State <= DAA_WAIT9; end if; when DAA_WAIT9 => if( DIV_Busy = '0' )then DAA_Digit_1 <= Quotient(3 downto 0); DAA_Digit_0 <= Remainder(3 downto 0); Conv_State <= DAA_DONE; end if; when DAA_DONE => DAA_Valid <= '1'; CNV_Done <= '1'; Conv_State <= IDLE; when others => null; end case; Product_AB <= OperandA * OperandB; Accumulator <= OperandABC + OperandD; end if; end process; -- Mult_proc: process( Clock) -- begin -- if( rising_edge(Clock) )then -- Product_AB <= OperandA * OperandB; -- end if; -- end process; U_DIV : entity work.intdiv generic map( Div_Width => DIVIDER_WIDTH, Reset_Level => Reset_Level ) port map( Clock => Clock, Reset => Reset, -- Enable => Div_Enable, Busy => Div_Busy, -- Dividend => Dividend, Divisor => Divisor, Quotient => Quotient, Remainder => Remainder ); end architecture;
Go to most recent revision | Compare with Previous | Blame | View Log