Warning, /frameworks/syntax-highlighting/autotests/input/light52_muldiv.vhdl is written in an unsupported language. File is not indexed.
0001 -------------------------------------------------------------------------------- 0002 -- light52_muldiv.vhdl -- Simple multiplier/divider module. 0003 -------------------------------------------------------------------------------- 0004 -- The 8051 mul and div instructions are both unsigned and operands are 8 bit. 0005 -- 0006 -- This module implements the division as a sequential state machine which takes 0007 -- 8 cycles to complete. 0008 -- The multiplier can be implemented as sequential or as combinational, in which 0009 -- case it will use a DSP block in those architectures that support it. 0010 -- No attempt has been made to make this module generic or reusable. 0011 -- 0012 -- If you want a combinational multiplier but don't want to waste a DSP block 0013 -- in this module, you need to modify this file adding whatever synthesis 0014 -- pragmas your tool of choice needs. 0015 -- 0016 -- Note that unlike the division state machine, the combinational product logic 0017 -- is always operating: when SEQUENTIAL_MULTIPLIER=true, prod_out equals 0018 -- data_a * data_b with a latency of 1 clock cycle, and mul_ready is hardwired 0019 -- to '1'. 0020 -- 0021 -- FIXME explain division algorithm. 0022 -------------------------------------------------------------------------------- 0023 -- GENERICS: 0024 -- 0025 -- SEQUENTIAL_MULTIPLIER -- Sequential vs. combinational multiplier. 0026 -- When true, a sequential implementation will be used for the multiplier, 0027 -- which will usually save a lot of logic or a dedicated multiplier. 0028 -- When false, a combinational registered multiplier will be used. 0029 -- 0030 -------------------------------------------------------------------------------- 0031 -- INTERFACE SIGNALS: 0032 -- 0033 -- clk : Clock, active rising edge. 0034 -- reset : Synchronous reset. Clears only the control registers not 0035 -- visible to the programmer -- not the output registers. 0036 -- 0037 -- data_a : Numerator input, should be connected to the ACC register. 0038 -- data_b : Denominator input, should be connected to the B register. 0039 -- start : Assert for 1 cycle to start the division state machine 0040 -- (and the product if SEQUENTIAL_MULTIPLIER=true); 0041 -- 0042 -- prod_out : Product output, valid only when mul_ready='1'. 0043 -- quot_out : Quotient output, valid only when div_ready='1'. 0044 -- rem_out : Remainder output, valid only when div_ready='1'. 0045 -- div_ov_out : Division overflow flag, valid only when div_ready='1'. 0046 -- mul_ov_out : Product overflow flag, valid only when mul_ready='1'. 0047 -- 0048 -- mul_ready : Asserted permanently if SEQUENTIAL_MULTIPLIER=false. 0049 -- div_ready : Deasserted the cycle after start is asserted. 0050 -- Asserted when the division has completed. 0051 -- 0052 -------------------------------------------------------------------------------- 0053 -- Copyright (C) 2012 Jose A. Ruiz 0054 -- 0055 -- This source file may be used and distributed without 0056 -- restriction provided that this copyright statement is not 0057 -- removed from the file and that any derivative work contains 0058 -- the original copyright notice and the associated disclaimer. 0059 -- 0060 -- This source file is free software; you can redistribute it 0061 -- and/or modify it under the terms of the GNU Lesser General 0062 -- Public License as published by the Free Software Foundation; 0063 -- either version 2.1 of the License, or (at your option) any 0064 -- later version. 0065 -- 0066 -- This source is distributed in the hope that it will be 0067 -- useful, but WITHOUT ANY WARRANTY; without even the implied 0068 -- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 0069 -- PURPOSE. See the GNU Lesser General Public License for more 0070 -- details. 0071 -- 0072 -- You should have received a copy of the GNU Lesser General 0073 -- Public License along with this source; if not, download it 0074 -- from http://www.opencores.org/lgpl.shtml 0075 -------------------------------------------------------------------------------- 0076 0077 library ieee; 0078 use ieee.std_logic_1164.all; 0079 use ieee.numeric_std.all; 0080 0081 use work.light52_pkg.all; 0082 use work.light52_ucode_pkg.all; 0083 0084 entity light52_muldiv is 0085 generic ( 0086 SEQUENTIAL_MULTIPLIER : boolean := false 0087 ); 0088 port( 0089 clk : in std_logic; 0090 reset : in std_logic; 0091 0092 data_a : in t_byte; 0093 data_b : in t_byte; 0094 start : in std_logic; 0095 0096 prod_out : out t_word; 0097 quot_out : out t_byte; 0098 rem_out : out t_byte; 0099 div_ov_out : out std_logic; 0100 mul_ov_out : out std_logic; 0101 0102 mul_ready : out std_logic; 0103 div_ready : out std_logic 0104 ); 0105 end entity light52_muldiv; 0106 0107 architecture sequential of light52_muldiv is 0108 0109 signal bit_ctr : integer range 0 to 8; 0110 0111 signal b_shift_reg : t_word; 0112 0113 signal den_ge_256 : std_logic; 0114 signal num_ge_den : std_logic; 0115 signal sub_num : std_logic; 0116 0117 signal denominator : t_byte; 0118 signal rem_reg : t_byte; 0119 signal quot_reg : t_byte; 0120 signal prod_reg : t_word; 0121 signal ready : std_logic; 0122 0123 signal load_regs : std_logic; 0124 0125 begin 0126 0127 -- Control logic --------------------------------------------------------------- 0128 0129 control_counter: process(clk) 0130 alias sig is <<signal g_test(0).i_test.sig : std_logic>>; 0131 begin 0132 if clk'event and clk='1' then 0133 if reset='1' then 0134 bit_ctr <= 8; 0135 else 0136 if load_regs='1' then 0137 bit_ctr <= 0; 0138 elsif bit_ctr /= 8 then 0139 bit_ctr <= bit_ctr + 1; 0140 end if; 0141 end if; 0142 end if; 0143 end process control_counter; 0144 0145 -- Internal signal ready is asserted after 8 cycles. 0146 -- The sequential multiplier will use this signal too, IF it takes 8 cycles. 0147 0148 ready <= '1' when bit_ctr >= 8 else '0'; 0149 0150 0151 ---- Divider logic ------------------------------------------------------------- 0152 0153 -- What we do is a simple base-2 'shift-and-subtract' algorithm that takes 0154 -- 8 cycles to complete. We can get away with this because we deal with unsigned 0155 -- numbers only. 0156 0157 divider_registers: process(clk) 0158 begin 0159 if clk'event and clk='1' then 0160 -- denominator shift register 0161 if load_regs='1' then 0162 b_shift_reg <= "0" & data_b & "0000000"; 0163 -- Division overflow can be determined upon loading B reg data. 0164 -- OV will be raised only on div-by-zero. 0165 if data_b=X"00" then 0166 div_ov_out <= '1'; 0167 else 0168 div_ov_out <= '0'; 0169 end if; 0170 else 0171 b_shift_reg <= "0" & b_shift_reg(b_shift_reg'high downto 1); 0172 end if; 0173 0174 -- numerator register 0175 if load_regs='1' then 0176 rem_reg <= data_a; 0177 elsif bit_ctr/=8 and sub_num='1' then 0178 rem_reg <= rem_reg - denominator; 0179 end if; 0180 0181 --- quotient register 0182 if load_regs='1' then 0183 quot_reg <= (others => '0'); 0184 elsif bit_ctr/=8 then 0185 quot_reg <= quot_reg(quot_reg'high-1 downto 0) & sub_num; 0186 end if; 0187 0188 load_regs <= start; 0189 end if; 0190 end process divider_registers; 0191 0192 denominator <= b_shift_reg(7 downto 0); 0193 0194 -- The 16-bit comparison between b_shift_reg (denominator) and the zero-extended 0195 -- rem_reg (numerator) can be simplified by splitting it in 2: 0196 -- If the shifted denominator high byte is not zero, it is >=256... 0197 den_ge_256 <= '1' when b_shift_reg(15 downto 8) /= X"00" else '0'; 0198 -- ...otherwise we need to compare the low bytes. 0199 num_ge_den <= '1' when rem_reg >= denominator else '0'; 0200 sub_num <= '1' when den_ge_256='0' and num_ge_den='1' else '0'; 0201 0202 0203 quot_out <= quot_reg; 0204 prod_out <= prod_reg; 0205 rem_out <= rem_reg; 0206 0207 div_ready <= ready; 0208 0209 ---- Multiplier logic ---------------------------------------------------------- 0210 0211 ---- Combinational multiplier ----------------------------- 0212 multiplier_combinational: if not SEQUENTIAL_MULTIPLIER generate 0213 0214 registered_combinational_multiplier:process(clk) 0215 begin 0216 if clk'event and clk='1' then 0217 prod_reg <= data_a * data_b; -- t_byte is unsigned 0218 end if; 0219 end process registered_combinational_multiplier; 0220 0221 -- The multiplier output is valid in the cycle after the operands are loaded, 0222 -- so by the time MUL is executed it's already done. 0223 mul_ready <= '1'; 0224 0225 mul_ov_out <= '1' when prod_reg(15 downto 8)/=X"00" else '0'; 0226 prod_out <= prod_reg; 0227 0228 end generate multiplier_combinational; 0229 0230 ---- Sequential multiplier -------------------------------- 0231 multiplier_sequential: if SEQUENTIAL_MULTIPLIER generate 0232 0233 assert false 0234 report "Sequential multiplier implementation not done yet."& 0235 " Use combinational implementation." 0236 severity failure; 0237 0238 end generate multiplier_sequential; 0239 0240 end sequential; 0241 0242 0243 with Types; use Types; 0244 with Files_Map; 0245 0246 package fixed_pkg is new IEEE.fixed_generic_pkg 0247 generic map ( 0248 fixed_overflow_style => IEEE.fixed_float_types.fixed_saturate, 0249 fixed_guard_bits => 3, 0250 no_warning => false 0251 ); 0252 0253 package p is 0254 type int_ptr is access integer; 0255 type rec is record 0256 data : std_logic_vector(31 downto 0); 0257 ack : std_logic; 0258 value : integer; 0259 link : rec_ptr; 0260 end record; 0261 type int_vec is array (integer range <>) of integer; 0262 type int_vec_ptr is access int_vec; 0263 procedure UNIFORM(variable SEED1, SEED2 : inout POSITIVE; variable X : out REAL); 0264 constant def_arr : t_int_array := (0 to 2 => 10); 0265 0266 -- type range 0267 type newInt is range -4 to 3; 0268 type CAPACITY is range 0 to 1E5 units 0269 pF; 0270 nF = 1000 pF; 0271 end units; 0272 0273 -- type protected 0274 type prot is protected 0275 function meth(a : int) return bit; 0276 end protected; 0277 0278 -- type protected body 0279 type prot is protected body 0280 variable var : positive; 0281 constant const : boolean; 0282 0283 function meth(a : int) return bit is 0284 begin 0285 end function; 0286 end protected body; 0287 0288 function \?=\ (L, R : BOOLEAN) return BOOLEAN; 0289 0290 end package; 0291 0292 package body p is 0293 function \?=\ (L, R : BOOLEAN) return BOOLEAN is 0294 begin 0295 if not (format(format'left) = '%') then 0296 report "to_string: Illegal format string """ & format & '"' 0297 severity error; 0298 return ""; 0299 end if; 0300 return L = R; 0301 end function \?=\; 0302 0303 procedure test is 0304 variable v : int_ptr; 0305 variable i : integer; 0306 begin 0307 v := null; 0308 deallocate(v); 0309 v := new integer; 0310 v := new integer'(5); 0311 v.all := 5; 0312 r.all.value := 1; 0313 a := new int_vec(1 to 3); 0314 a.all(5) := 2; 0315 a(1 to 2) := (1, 2); 0316 s := new string'(""); 0317 end procedure; 0318 0319 procedure test2(x : inout rec_ptr) is 0320 begin 0321 x.value := x.value + 1; 0322 end procedure; 0323 0324 procedure test3 is 0325 type a; 0326 type a is access integer; 0327 variable v : a; 0328 begin 0329 end procedure; 0330 0331 type int_ptr_array is array (integer range <>) of int_ptr; 0332 0333 procedure tets4 is 0334 type bvp is access bit_vector; 0335 variable y : int_ptr(1 to 3) := int_ptr'(null); 0336 begin 0337 end procedure; 0338 0339 procedure Restore_Origin (Mark : Instance_Index_Type) is 0340 begin 0341 for I in reverse Mark + 1 .. Prev_Instance_Table.Last loop 0342 declare 0343 El : Instance_Entry_Type renames Prev_Instance_Table.Table (I); 0344 begin 0345 Origin_Table.Table (El.N) := El.Old_Origin; 0346 end; 0347 end loop; 0348 Prev_Instance_Table.Set_Last (Mark); 0349 end Restore_Origin; 0350 0351 -- Instantiate a list. Simply create a new list and instantiate nodes of 0352 -- that list. 0353 function Instantiate_Iir_List (L : Iir_List; Is_Ref : Boolean) 0354 return Iir_List 0355 is 0356 Res : Iir_List; 0357 El : Iir; 0358 begin 0359 case to_integer(unsigned(CTRL_REF(x*4+3 downto x*4))) is 0360 when Null_Iir_List 0361 | Iir_List_All => 0362 return L; 0363 when others => 0364 It := List_Iterate (L); 0365 while Is_Valid (It) loop 0366 El := Get_Element (It); 0367 Append_Element (Res, Instantiate_Iir (El, Is_Ref)); 0368 end loop; 0369 for I in Flist_First .. Flist_Last (L) loop 0370 Set_Nth_Element (Res, I, Instantiate_Iir (El, Is_Ref)); 0371 end loop; 0372 return Res; 0373 end case; 0374 end Instantiate_Iir_List; 0375 end package body; 0376 0377 -- Library bar 0378 context foo.test_context; 0379 0380 context foo is 0381 context foo.test_context; 0382 end context foo; 0383 0384 entity concat is 0385 end entity; 0386 0387 entity foo is 0388 port ( 0389 x : in my_int ); 0390 end entity; 0391 0392 architecture t of concat is 0393 type int_array is array (integer range <>) of integer; 0394 type small is range 1 to 3; 0395 0396 component or_entity is 0397 port( 0398 input_1: in std_logic; 0399 output: out std_logic 0400 ); 0401 end component; 0402 begin 0403 process 0404 variable s : string(1 to 5); 0405 variable t : int_array(1 to 2); 0406 variable c : bit_vector(1 to 4); 0407 begin 0408 x := ( 1, 2, 3 ); 0409 z := x & y; 0410 w := 1 & x; 0411 s := 'h' & string'("ello"); 0412 assert "10" = (b(1) & "0"); 0413 wait; 0414 end process; 0415 0416 function CounterVal(Seconds : integer := 0) return integer is 0417 variable TotalSeconds : interger; 0418 begin 0419 TotalSeconds := Seconds + Minutes * 60; 0420 return TotalSeconds * ClockFrequencyHz -1; 0421 end function; 0422 0423 type enum_type is (a, b, c, ..., z); 0424 type int_array is array(3 downto 0) of integer; 0425 0426 subtype addr_int is integer range 0 to 65535; 0427 subtype sub_enum_type is enum_type range a to m; 0428 0429 inst1: entity work.counter1(rtl) 0430 generic map (BITS1 => 8) 0431 port map ( 0432 clk1 => Clock, 0433 DATA_OUT => pwm_data_o(3 downto 5), 0434 COMP_IN(1 downto 0) => compensate_i, 0435 WRITE_IN => (others => '0') 0436 ); 0437 0438 inst2: component counter2 0439 generic map (BITS1 => 8) 0440 port map (clk1 => Clock); 0441 0442 inst3: configuration counter3 0443 generic map (BITS1 => 8) 0444 port map (clk1 => Clock); 0445 0446 THE_PWM_GEN : pwm_generator 0447 generic map( 0448 dsfds => ds 0449 ) 0450 port map( 0451 CLK => clk_i, 0452 DATA_IN => pwm_data_i, 0453 DATA_OUT => pwm_data_o(3 downto 5), 0454 COMP_IN(1 downto 0) => compensate_i, 0455 WRITE_IN => (others => '0') 0456 ); 0457 0458 end architecture; 0459 0460 architecture a2 of e is 0461 function ">"(a, b: my_int) return boolean; 0462 begin 0463 process is 0464 variable x, y : my_int; 0465 begin 0466 assert x > y; 0467 assert x < y; -- Error 0468 end process; 0469 0470 billowitch_tc586: block is 0471 type real_cons_vector is array (15 downto 0) of real; 0472 type real_cons_vector_file is file of real_cons_vector; 0473 constant C19 : real_cons_vector := (others => 3.0); 0474 begin 0475 end block; 0476 end architecture; 0477 0478 architecture arch of ent is 0479 begin 0480 LL: if test=10 generate 0481 begin 0482 end; 0483 elsif test=5 generate 0484 begin 0485 end; 0486 end generate; 0487 0488 LL: if l1: SPEED = "fast" generate 0489 elsif test=5 generate 0490 end generate; 0491 end architecture arch; 0492 0493 0494 architecture thing_arch of designthing is 0495 0496 component pwm_generator 0497 port( 0498 CLK : in std_logic; 0499 DATA_IN : in std_logic_vector(15 downto 0); 0500 ); 0501 end component pwm_generator; 0502 0503 attribute NOM_FREQ : string; 0504 attribute NOM_FREQ of clk_source : label is "133.00"; 0505 signal clk_i : std_logic; 0506 0507 begin 0508 0509 gen_no_comp: if TEMP = 0 generate 0510 compensate_i <= (others => '0'); 0511 end generate; 0512 0513 gen_no_comp: for i in 0 to TEMP generate 0514 compensate_i <= (others => '0') after 10 ns; 0515 compensate_i <= (others => '0') ; 0516 end generate; 0517 0518 --------------------------------------------------------------------------- 0519 -- LED blinking when activity on inputs 0520 --------------------------------------------------------------------------- 0521 PROC_TIMER : process begin 0522 wait until rising_edge(clk_i); 0523 timer <= timer + 1; 0524 wait for 10 ns; 0525 leds <= (last_inp xor inp_status(3 downto 0)) or leds or last_leds; 0526 if timer = 0 then 0527 leds <= not inp_status(3 downto 0); 0528 last_leds <= x"0"; 0529 elsif gf then 0530 fdsa <= '1'; 0531 end if; 0532 0533 xz: for x in 0 to 7 loop 0534 dsadf; 0535 end loop; 0536 0537 case c is 0538 when XXX => 0539 c <= 1; 0540 d <= 21321; 0541 when YYYY => 0542 c <= 2; 0543 end case; 0544 end process; 0545 0546 0547 generate_with_begin: if TEMP = 0 generate 0548 signal : test : std_logic; 0549 begin 0550 compensate_i <= (others => '0'); 0551 if timer = 0 then 0552 leds <= not inp_status(3 downto 0); 0553 last_leds <= x"0"; 0554 elsif gf then 0555 fdsa <= '1'; 0556 end if; 0557 end generate generate_with_begin; 0558 0559 PROC_TIMER : process 0560 variable x : std_logic; 0561 begin 0562 x := '0'; 0563 end process PROC_TIMER; 0564 0565 end architecture thing_arc; --this is not correct (wrong name) 0566 0567 1+1 0568 2ns 0569 0570 1_2_3 0571 12_3 0572 1.2 0573 1.2_3 0574 1_3.2_3 0575 12_3e+1 0576 12_3e-1 0577 12_3e1_1 0578 12_3.4e1_1 0579 12_3e1_ 0580 12_3e 0581 0582 2#1_2_3#E+8 0583 2#1_2.3#E+8 0584 2#1_f2.3# 0585 0586 3.14159_26536 -- A literal of type universal_real. 0587 5280 -- A literal of type universal_integer. 0588 10.7 ns -- A literal of a physical type. 0589 O"4777" -- A bit string literal. 0590 "54LS281" -- A string literal. 0591 "" -- A string literal representing a null array. 0592 B"1111_1111_1111" -- Equivalent to the string literal "111111111111". 0593 X"FFF" -- Equivalent to B"1111_1111_1111". 0594 O"777" -- Equivalent to B"111_111_111". 0595 X"777" -- Equivalent to B"0111_0111_0111". 0596 B"XXXX_01LH" -- Equivalent to the string literal "XXXX01LH" 0597 UO"27" -- Equivalent to B"010_111" 0598 UO"2C" -- Equivalent to B"011_CCC" 0599 SX"3W" -- Equivalent to B"0011_WWWW" 0600 D"35" -- Equivalent to B"100011" 0601 12UB"X1" -- Equivalent to B"0000_0000_00X1" 0602 12SB"X1" -- Equivalent to B"XXXX_XXXX_XXX1" 0603 12UX"F-" -- Equivalent to B"0000_1111_----" 0604 12SX"F-" -- Equivalent to B"1111_1111_----" 0605 12D"13" -- Equivalent to B"0000_0000_1101" 0606 12UX"000WWW" -- Equivalent to B"WWWW_WWWW_WWWW" 0607 12SX"FFFC00" -- Equivalent to B"1100_0000_0000" 0608 12SX"XXXX00" -- Equivalent to B"XXXX_0000_0000" 0609 8D"511" -- Error 0610 8UO"477" -- Error 0611 8SX"0FF" -- Error 0612 8SX"FXX" -- Error