Files
RedBear-OS/local/recipes/kde/kf6-syntaxhighlighting/source/autotests/folding/light52_muldiv.vhdl.fold
T

613 lines
24 KiB
Plaintext

--------------------------------------------------------------------------------
-- light52_muldiv.vhdl -- Simple multiplier/divider module.
--------------------------------------------------------------------------------
-- The 8051 mul and div instructions are both unsigned and operands are 8 bit.
--
-- This module implements the division as a sequential state machine which takes
-- 8 cycles to complete.
-- The multiplier can be implemented as sequential or as combinational, in which
-- case it will use a DSP block in those architectures that support it.
-- No attempt has been made to make this module generic or reusable.
--
-- If you want a combinational multiplier but don't want to waste a DSP block
-- in this module, you need to modify this file adding whatever synthesis
-- pragmas your tool of choice needs.
--
-- Note that unlike the division state machine, the combinational product logic
-- is always operating: when SEQUENTIAL_MULTIPLIER=true, prod_out equals
-- data_a * data_b with a latency of 1 clock cycle, and mul_ready is hardwired
-- to '1'.
--
-- FIXME explain division algorithm.
--------------------------------------------------------------------------------
-- GENERICS:
--
-- SEQUENTIAL_MULTIPLIER -- Sequential vs. combinational multiplier.
-- When true, a sequential implementation will be used for the multiplier,
-- which will usually save a lot of logic or a dedicated multiplier.
-- When false, a combinational registered multiplier will be used.
--
--------------------------------------------------------------------------------
-- INTERFACE SIGNALS:
--
-- clk : Clock, active rising edge.
-- reset : Synchronous reset. Clears only the control registers not
-- visible to the programmer -- not the output registers.
--
-- data_a : Numerator input, should be connected to the ACC register.
-- data_b : Denominator input, should be connected to the B register.
-- start : Assert for 1 cycle to start the division state machine
-- (and the product if SEQUENTIAL_MULTIPLIER=true);
--
-- prod_out : Product output, valid only when mul_ready='1'.
-- quot_out : Quotient output, valid only when div_ready='1'.
-- rem_out : Remainder output, valid only when div_ready='1'.
-- div_ov_out : Division overflow flag, valid only when div_ready='1'.
-- mul_ov_out : Product overflow flag, valid only when mul_ready='1'.
--
-- mul_ready : Asserted permanently if SEQUENTIAL_MULTIPLIER=false.
-- div_ready : Deasserted the cycle after start is asserted.
-- Asserted when the division has completed.
--
--------------------------------------------------------------------------------
-- Copyright (C) 2012 Jose A. Ruiz
--
-- This source file may be used and distributed without
-- restriction provided that this copyright statement is not
-- removed from the file and that any derivative work contains
-- the original copyright notice and the associated disclaimer.
--
-- This source file is free software; you can redistribute it
-- and/or modify it under the terms of the GNU Lesser General
-- Public License as published by the Free Software Foundation;
-- either version 2.1 of the License, or (at your option) any
-- later version.
--
-- This source 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 Lesser General Public License for more
-- details.
--
-- You should have received a copy of the GNU Lesser General
-- Public License along with this source; if not, download it
-- from http://www.opencores.org/lgpl.shtml
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.light52_pkg.all;
use work.light52_ucode_pkg.all;
entity <beginfold id='1'>light52_muldiv</beginfold id='1'> is
generic (
SEQUENTIAL_MULTIPLIER : boolean := false
);
port(
clk : in std_logic;
reset : in std_logic;
data_a : in t_byte;
data_b : in t_byte;
start : in std_logic;
prod_out : out t_word;
quot_out : out t_byte;
rem_out : out t_byte;
div_ov_out : out std_logic;
mul_ov_out : out std_logic;
mul_ready : out std_logic;
div_ready : out std_logic
);
<endfold id='1'>end entity light52_muldiv;</endfold id='1'>
architecture <beginfold id='2'>sequential</beginfold id='2'> of light52_muldiv is
signal bit_ctr : integer range 0 to 8;
signal b_shift_reg : t_word;
signal den_ge_256 : std_logic;
signal num_ge_den : std_logic;
signal sub_num : std_logic;
signal denominator : t_byte;
signal rem_reg : t_byte;
signal quot_reg : t_byte;
signal prod_reg : t_word;
signal ready : std_logic;
signal load_regs : std_logic;
begin
-- Control logic ---------------------------------------------------------------
control_counter: <beginfold id='3'>process</beginfold id='3'>(clk)
alias sig is <<signal g_test(0).i_test.sig : std_logic>>;
begin
<beginfold id='4'>if</beginfold id='4'> clk'event and clk='1' then
<beginfold id='4'>if</beginfold id='4'> reset='1' then
bit_ctr <= 8;
else
<beginfold id='4'>if</beginfold id='4'> load_regs='1' then
bit_ctr <= 0;
elsif bit_ctr /= 8 then
bit_ctr <= bit_ctr + 1;
<endfold id='4'>end if;</endfold id='4'>
<endfold id='4'>end if;</endfold id='4'>
<endfold id='4'>end if;</endfold id='4'>
<endfold id='3'>end process control_counter;</endfold id='3'>
-- Internal signal ready is asserted after 8 cycles.
-- The sequential multiplier will use this signal too, IF it takes 8 cycles.
ready <= '1' when bit_ctr >= 8 else '0';
---- Divider logic -------------------------------------------------------------
-- What we do is a simple base-2 'shift-and-subtract' algorithm that takes
-- 8 cycles to complete. We can get away with this because we deal with unsigned
-- numbers only.
divider_registers: <beginfold id='3'>process</beginfold id='3'>(clk)
begin
<beginfold id='4'>if</beginfold id='4'> clk'event and clk='1' then
-- denominator shift register
<beginfold id='4'>if</beginfold id='4'> load_regs='1' then
b_shift_reg <= "0" & data_b & "0000000";
-- Division overflow can be determined upon loading B reg data.
-- OV will be raised only on div-by-zero.
<beginfold id='4'>if</beginfold id='4'> data_b=X"00" then
div_ov_out <= '1';
else
div_ov_out <= '0';
<endfold id='4'>end if;</endfold id='4'>
else
b_shift_reg <= "0" & b_shift_reg(b_shift_reg'high downto 1);
<endfold id='4'>end if;</endfold id='4'>
-- numerator register
<beginfold id='4'>if</beginfold id='4'> load_regs='1' then
rem_reg <= data_a;
elsif bit_ctr/=8 and sub_num='1' then
rem_reg <= rem_reg - denominator;
<endfold id='4'>end if;</endfold id='4'>
--- quotient register
<beginfold id='4'>if</beginfold id='4'> load_regs='1' then
quot_reg <= (others => '0');
elsif bit_ctr/=8 then
quot_reg <= quot_reg(quot_reg'high-1 downto 0) & sub_num;
<endfold id='4'>end if;</endfold id='4'>
load_regs <= start;
<endfold id='4'>end if;</endfold id='4'>
<endfold id='3'>end process divider_registers;</endfold id='3'>
denominator <= b_shift_reg(7 downto 0);
-- The 16-bit comparison between b_shift_reg (denominator) and the zero-extended
-- rem_reg (numerator) can be simplified by splitting it in 2:
-- If the shifted denominator high byte is not zero, it is >=256...
den_ge_256 <= '1' when b_shift_reg(15 downto 8) /= X"00" else '0';
-- ...otherwise we need to compare the low bytes.
num_ge_den <= '1' when rem_reg >= denominator else '0';
sub_num <= '1' when den_ge_256='0' and num_ge_den='1' else '0';
quot_out <= quot_reg;
prod_out <= prod_reg;
rem_out <= rem_reg;
div_ready <= ready;
---- Multiplier logic ----------------------------------------------------------
---- Combinational multiplier -----------------------------
multiplier_combinational: <beginfold id='4'>if</beginfold id='4'> not SEQUENTIAL_MULTIPLIER generate
registered_combinational_multiplier:<beginfold id='3'>process</beginfold id='3'>(clk)
begin
<beginfold id='4'>if</beginfold id='4'> clk'event and clk='1' then
prod_reg <= data_a * data_b; -- t_byte is unsigned
<endfold id='4'>end if;</endfold id='4'>
<endfold id='3'>end process registered_combinational_multiplier;</endfold id='3'>
-- The multiplier output is valid in the cycle after the operands are loaded,
-- so by the time MUL is executed it's already done.
mul_ready <= '1';
mul_ov_out <= '1' when prod_reg(15 downto 8)/=X"00" else '0';
prod_out <= prod_reg;
<endfold id='4'>end generate multiplier_combinational;</endfold id='4'>
---- Sequential multiplier --------------------------------
multiplier_sequential: <beginfold id='4'>if</beginfold id='4'> SEQUENTIAL_MULTIPLIER generate
assert false
report "Sequential multiplier implementation not done yet."&
" Use combinational implementation."
severity failure;
<endfold id='4'>end generate multiplier_sequential;</endfold id='4'>
<endfold id='2'>end sequential;</endfold id='2'>
with Types; use Types;
with Files_Map;
package <beginfold id='5'>fixed_pkg</beginfold id='5'> is new IEEE.fixed_generic_pkg
generic map <beginfold id='6'>(</beginfold id='6'>
fixed_overflow_style => IEEE.fixed_float_types.fixed_saturate,
fixed_guard_bits => 3,
no_warning => false
<endfold id='6'>)</endfold id='6'><endfold id='5'>;</endfold id='5'>
package <beginfold id='5'>p</beginfold id='5'> is
type int_ptr is access integer;
type rec is <beginfold id='7'>record</beginfold id='7'>
data : std_logic_vector(31 downto 0);
ack : std_logic;
value : integer;
link : rec_ptr;
<endfold id='7'>end record;</endfold id='7'>
type int_vec is array (integer range <>) of integer;
type int_vec_ptr is access int_vec;
<beginfold id='8'>procedure</beginfold id='8'> UNIFORM(variable SEED1, SEED2 : inout POSITIVE; variable X : out REAL)<endfold id='8'>;</endfold id='8'>
constant def_arr : t_int_array := (0 to 2 => 10);
-- type range
type newInt is range -4 to 3;
type CAPACITY is range 0 to 1E5 <beginfold id='9'>units</beginfold id='9'>
pF;
nF = 1000 pF;
<endfold id='9'>end units;</endfold id='9'>
-- type protected
type prot is <beginfold id='10'>protected</beginfold id='10'>
function meth(a : int) return bit;
<endfold id='10'>end protected;</endfold id='10'>
-- type protected body
type prot is <beginfold id='10'>protected</beginfold id='10'> body
variable var : positive;
constant const : boolean;
function meth(a : int) return bit <beginfold id='11'>is</beginfold id='11'>
begin
<endfold id='11'>end function;</endfold id='11'>
<endfold id='10'>end protected body;</endfold id='10'>
function \?=\ (L, R : BOOLEAN) return BOOLEAN;
<endfold id='5'>end package;</endfold id='5'>
package body <beginfold id='12'>p</beginfold id='12'> is
function \?=\ (L, R : BOOLEAN) return BOOLEAN <beginfold id='11'>is</beginfold id='11'>
begin
<beginfold id='4'>if</beginfold id='4'> not (format(format'left) = '%') then
report "to_string: Illegal format string """ & format & '"'
severity error;
return "";
<endfold id='4'>end if;</endfold id='4'>
return L = R;
<endfold id='11'>end function \?=\;</endfold id='11'>
<beginfold id='8'>procedure</beginfold id='8'> test is
variable v : int_ptr;
variable i : integer;
<endfold id='8'></endfold id='8'><beginfold id='8'>begin</beginfold id='8'>
v := null;
deallocate(v);
v := new integer;
v := new integer'(5);
v.all := 5;
r.all.value := 1;
a := new int_vec(1 to 3);
a.all(5) := 2;
a(1 to 2) := (1, 2);
s := new string'("");
<endfold id='8'>end procedure;</endfold id='8'>
<beginfold id='8'>procedure</beginfold id='8'> test2(x : inout rec_ptr) is
<endfold id='8'></endfold id='8'><beginfold id='8'>begin</beginfold id='8'>
x.value := x.value + 1;
<endfold id='8'>end procedure;</endfold id='8'>
<beginfold id='8'>procedure</beginfold id='8'> test3 is
type a;
type a is access integer;
variable v : a;
<endfold id='8'></endfold id='8'><beginfold id='8'>begin</beginfold id='8'>
<endfold id='8'>end procedure;</endfold id='8'>
type int_ptr_array is array (integer range <>) of int_ptr;
<beginfold id='8'>procedure</beginfold id='8'> tets4 is
type bvp is access bit_vector;
variable y : int_ptr(1 to 3) := int_ptr'(null);
<endfold id='8'></endfold id='8'><beginfold id='8'>begin</beginfold id='8'>
<endfold id='8'>end procedure;</endfold id='8'>
<beginfold id='8'>procedure</beginfold id='8'> Restore_Origin (Mark : Instance_Index_Type) is
<endfold id='8'></endfold id='8'><beginfold id='8'>begin</beginfold id='8'>
for I in reverse Mark + 1 .. Prev_Instance_Table.Last <beginfold id='13'>loop</beginfold id='13'>
<beginfold id='14'>declare</beginfold id='14'>
El : Instance_Entry_Type renames Prev_Instance_Table.Table (I);
begin
Origin_Table.Table (El.N) := El.Old_Origin;
<endfold id='14'>end;</endfold id='14'>
<endfold id='13'>end loop;</endfold id='13'>
Prev_Instance_Table.Set_Last (Mark);
<endfold id='8'>end Restore_Origin;</endfold id='8'>
-- Instantiate a list. Simply create a new list and instantiate nodes of
-- that list.
function Instantiate_Iir_List (L : Iir_List; Is_Ref : Boolean)
return Iir_List
<beginfold id='11'>is</beginfold id='11'>
Res : Iir_List;
El : Iir;
begin
<beginfold id='15'>case</beginfold id='15'> to_integer(unsigned(CTRL_REF(x*4+3 downto x*4))) is
when Null_Iir_List
| Iir_List_All <beginfold id='16'>=></beginfold id='16'>
return L;
<endfold id='16'>when</endfold id='16'> others <beginfold id='16'>=></beginfold id='16'>
It := List_Iterate (L);
while Is_Valid (It) <beginfold id='13'>loop</beginfold id='13'>
El := Get_Element (It);
Append_Element (Res, Instantiate_Iir (El, Is_Ref));
<endfold id='13'>end loop;</endfold id='13'>
for I in Flist_First .. Flist_Last (L) <beginfold id='13'>loop</beginfold id='13'>
Set_Nth_Element (Res, I, Instantiate_Iir (El, Is_Ref));
<endfold id='13'>end loop;</endfold id='13'>
return Res;
<endfold id='16'></endfold id='16'><endfold id='15'>end case;</endfold id='15'>
<endfold id='11'>end Instantiate_Iir_List;</endfold id='11'>
<endfold id='12'>end package body;</endfold id='12'>
-- Library bar
context foo.test_context;
context <beginfold id='17'>foo</beginfold id='17'> is
context foo.test_context;
<endfold id='17'>end context foo;</endfold id='17'>
entity <beginfold id='1'>concat</beginfold id='1'> is
<endfold id='1'>end entity;</endfold id='1'>
entity <beginfold id='1'>foo</beginfold id='1'> is
port (
x : in my_int );
<endfold id='1'>end entity;</endfold id='1'>
architecture <beginfold id='2'>t</beginfold id='2'> of concat is
type int_array is array (integer range <>) of integer;
type small is range 1 to 3;
component <beginfold id='18'>or_entity</beginfold id='18'> is
port(
input_1: in std_logic;
output: out std_logic
);
<endfold id='18'>end component;</endfold id='18'>
begin
<beginfold id='3'>process</beginfold id='3'>
variable s : string(1 to 5);
variable t : int_array(1 to 2);
variable c : bit_vector(1 to 4);
begin
x := ( 1, 2, 3 );
z := x & y;
w := 1 & x;
s := 'h' & string'("ello");
assert "10" = (b(1) & "0");
wait;
<endfold id='3'>end process;</endfold id='3'>
function CounterVal(Seconds : integer := 0) return integer <beginfold id='11'>is</beginfold id='11'>
variable TotalSeconds : interger;
begin
TotalSeconds := Seconds + Minutes * 60;
return TotalSeconds * ClockFrequencyHz -1;
<endfold id='11'>end function;</endfold id='11'>
type enum_type is (a, b, c, ..., z);
type int_array is array(3 downto 0) of integer;
subtype addr_int is integer range 0 to 65535;
subtype sub_enum_type is enum_type range a to m;
inst1: entity <beginfold id='19'>work.counter1</beginfold id='19'>(rtl)
generic map <beginfold id='6'>(</beginfold id='6'>BITS1 => 8<endfold id='6'>)</endfold id='6'>
port map <beginfold id='6'>(</beginfold id='6'>
clk1 => Clock,
DATA_OUT => pwm_data_o(3 downto 5),
COMP_IN(1 downto 0) => compensate_i,
WRITE_IN => (others => '0')
<endfold id='6'>)</endfold id='6'><endfold id='19'>;</endfold id='19'>
inst2: component <beginfold id='19'>counter2</beginfold id='19'>
generic map <beginfold id='6'>(</beginfold id='6'>BITS1 => 8<endfold id='6'>)</endfold id='6'>
port map <beginfold id='6'>(</beginfold id='6'>clk1 => Clock<endfold id='6'>)</endfold id='6'><endfold id='19'>;</endfold id='19'>
inst3: configuration <beginfold id='19'>counter3</beginfold id='19'>
generic map <beginfold id='6'>(</beginfold id='6'>BITS1 => 8<endfold id='6'>)</endfold id='6'>
port map <beginfold id='6'>(</beginfold id='6'>clk1 => Clock<endfold id='6'>)</endfold id='6'><endfold id='19'>;</endfold id='19'>
THE_PWM_GEN : <beginfold id='19'>pwm_generator</beginfold id='19'>
generic map<beginfold id='6'>(</beginfold id='6'>
dsfds => ds
<endfold id='6'>)</endfold id='6'>
port map<beginfold id='6'>(</beginfold id='6'>
CLK => clk_i,
DATA_IN => pwm_data_i,
DATA_OUT => pwm_data_o(3 downto 5),
COMP_IN(1 downto 0) => compensate_i,
WRITE_IN => (others => '0')
<endfold id='6'>)</endfold id='6'><endfold id='19'>;</endfold id='19'>
<endfold id='2'>end architecture;</endfold id='2'>
architecture <beginfold id='2'>a2</beginfold id='2'> of e is
function ">"(a, b: my_int) return boolean;
begin
<beginfold id='3'>process</beginfold id='3'> is
variable x, y : my_int;
begin
assert x > y;
assert x < y; -- Error
<endfold id='3'>end process;</endfold id='3'>
billowitch_tc586: <beginfold id='10'>block</beginfold id='10'> is
type real_cons_vector is array (15 downto 0) of real;
type real_cons_vector_file is file of real_cons_vector;
constant C19 : real_cons_vector := (others => 3.0);
begin
<endfold id='10'>end block;</endfold id='10'>
<endfold id='2'>end architecture;</endfold id='2'>
architecture <beginfold id='2'>arch</beginfold id='2'> of ent is
begin
LL: <beginfold id='4'>if</beginfold id='4'> test=10 generate
begin
end;
elsif test=5 generate
begin
end;
<endfold id='4'>end generate;</endfold id='4'>
LL: <beginfold id='4'>if</beginfold id='4'> l1: SPEED = "fast" generate
elsif test=5 generate
<endfold id='4'>end generate;</endfold id='4'>
<endfold id='2'>end architecture arch;</endfold id='2'>
architecture <beginfold id='2'>thing_arch</beginfold id='2'> of designthing is
component <beginfold id='18'>pwm_generator</beginfold id='18'>
port(
CLK : in std_logic;
DATA_IN : in std_logic_vector(15 downto 0);
);
<endfold id='18'>end component pwm_generator;</endfold id='18'>
attribute NOM_FREQ : string;
attribute NOM_FREQ of clk_source : label is "133.00";
signal clk_i : std_logic;
begin
gen_no_comp: <beginfold id='4'>if</beginfold id='4'> TEMP = 0 generate
compensate_i <= (others => '0');
<endfold id='4'>end generate;</endfold id='4'>
gen_no_comp: <beginfold id='13'>for</beginfold id='13'> i in 0 to TEMP generate
compensate_i <= (others => '0') after 10 ns;
compensate_i <= (others => '0') ;
<endfold id='13'>end generate;</endfold id='13'>
---------------------------------------------------------------------------
-- LED blinking when activity on inputs
---------------------------------------------------------------------------
PROC_TIMER : <beginfold id='3'>process</beginfold id='3'> begin
wait until rising_edge(clk_i);
timer <= timer + 1;
wait for 10 ns;
leds <= (last_inp xor inp_status(3 downto 0)) or leds or last_leds;
<beginfold id='4'>if</beginfold id='4'> timer = 0 then
leds <= not inp_status(3 downto 0);
last_leds <= x"0";
elsif gf then
fdsa <= '1';
<endfold id='4'>end if;</endfold id='4'>
xz: for x in 0 to 7 <beginfold id='13'>loop</beginfold id='13'>
dsadf;
<endfold id='13'>end loop;</endfold id='13'>
<beginfold id='15'>case</beginfold id='15'> c is
when XXX <beginfold id='16'>=></beginfold id='16'>
c <= 1;
d <= 21321;
<endfold id='16'>when</endfold id='16'> YYYY <beginfold id='16'>=></beginfold id='16'>
c <= 2;
<endfold id='16'></endfold id='16'><endfold id='15'>end case;</endfold id='15'>
<endfold id='3'>end process;</endfold id='3'>
generate_with_begin: <beginfold id='4'>if</beginfold id='4'> TEMP = 0 generate
signal : test : std_logic;
begin
compensate_i <= (others => '0');
<beginfold id='4'>if</beginfold id='4'> timer = 0 then
leds <= not inp_status(3 downto 0);
last_leds <= x"0";
elsif gf then
fdsa <= '1';
<endfold id='4'>end if;</endfold id='4'>
<endfold id='4'>end generate generate_with_begin;</endfold id='4'>
PROC_TIMER : <beginfold id='3'>process</beginfold id='3'>
variable x : std_logic;
begin
x := '0';
<endfold id='3'>end process PROC_TIMER;</endfold id='3'>
<endfold id='2'>end</endfold id='2'> architecture thing_arc; --this is not correct (wrong name)
1+1
2ns
1_2_3
12_3
1.2
1.2_3
1_3.2_3
12_3e+1
12_3e-1
12_3e1_1
12_3.4e1_1
12_3e1_
12_3e
2#1_2_3#E+8
2#1_2.3#E+8
2#1_f2.3#
3.14159_26536 -- A literal of type universal_real.
5280 -- A literal of type universal_integer.
10.7 ns -- A literal of a physical type.
O"4777" -- A bit string literal.
"54LS281" -- A string literal.
"" -- A string literal representing a null array.
B"1111_1111_1111" -- Equivalent to the string literal "111111111111".
X"FFF" -- Equivalent to B"1111_1111_1111".
O"777" -- Equivalent to B"111_111_111".
X"777" -- Equivalent to B"0111_0111_0111".
B"XXXX_01LH" -- Equivalent to the string literal "XXXX01LH"
UO"27" -- Equivalent to B"010_111"
UO"2C" -- Equivalent to B"011_CCC"
SX"3W" -- Equivalent to B"0011_WWWW"
D"35" -- Equivalent to B"100011"
12UB"X1" -- Equivalent to B"0000_0000_00X1"
12SB"X1" -- Equivalent to B"XXXX_XXXX_XXX1"
12UX"F-" -- Equivalent to B"0000_1111_----"
12SX"F-" -- Equivalent to B"1111_1111_----"
12D"13" -- Equivalent to B"0000_0000_1101"
12UX"000WWW" -- Equivalent to B"WWWW_WWWW_WWWW"
12SX"FFFC00" -- Equivalent to B"1100_0000_0000"
12SX"XXXX00" -- Equivalent to B"XXXX_0000_0000"
8D"511" -- Error
8UO"477" -- Error
8SX"0FF" -- Error
8SX"FXX" -- Error