Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronic Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Register Log in

help require with rtl coding...........

Status
Not open for further replies.

umairsiddiqui

Full Member level 2
Joined
Apr 13, 2004
Messages
144
Helped
7
Reputation
14
Reaction score
1
Trophy points
1,298
Location
Sweden
Activity points
1,436
consider this code...
which is arithmetic unit of ALU:
supports: ADD, SUB, ADC and SBB
problem is that given code require 17bit subtractor, 16-bit adder, and 16-bit adder with carry-in. please help how to reduce it size... :?


Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;


entity alu is
    Port ( a : in std_logic_vector(15 downto 0);
           b : in std_logic_vector(15 downto 0);
           cin : in std_logic;
           op : in std_logic_vector(1 downto 0);
           c : out std_logic_vector(15 downto 0);
           cout : out std_logic;
           ofl : out std_logic);
end alu;

architecture Behavioral of alu is
begin   

   process(a, b, cin, op)      
      variable c_select : std_logic;
      variable a_temp, 
               b_temp,
               c_temp : std_logic_vector(16 downto 0);

   begin
      a_temp := "0" & a;
      b_temp := "0" & b;
      case op(1) is
         when '0' => c_select := '0';
         when '1' => c_select := cin;
         when others => c_select := '0';
      end case;
      case op(0) is
         when '0' => c_temp := a_temp + b_temp + c_select;
         when '1' => c_temp := a_temp - (b_temp + c_select);
         when others => c_temp := (others => '0');
      end case;
      c <= c_temp(15 downto 0);
      cout <= c_temp(16);
      ofl <= c_temp(15) xor c_temp(14);
   end process;

end Behavioral;
 

nand_gates

Advanced Member level 3
Joined
Jul 19, 2004
Messages
892
Helped
174
Reputation
348
Reaction score
51
Trophy points
1,308
Activity points
6,803
Hi umair,
Check out the code below I can't optimise it further!
Please do the testing first its untested.
Hope this helps you!

Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity alu is
    Port ( a : in std_logic_vector(15 downto 0);
           b : in std_logic_vector(15 downto 0);
           cin : in std_logic;
           op : in std_logic_vector(1 downto 0);
           c : out std_logic_vector(15 downto 0);
           cout : out std_logic;
           ofl : out std_logic);
end alu;

architecture Behavioral of alu is
  signal b_int : std_logic_vector(15 downto 0);
  signal cy_int : std_logic_vector(15 downto 0);
  signal cin_int : std_logic;
begin
  cin_int <= op(1) and cin;
  b_int <= a xor b xor (op(0)&op(0)&op(0)&op(0)&op(0)&op(0)&op(0)&op(0)&op(0)&op(0)&op(0)&op(0)&op(0)&op(0)&op(0));
  cy_int(0)  <= cin_int    when  b_int(0)  = '1' else a(0);
  cy_int(1)  <= cy_int(0)  when  b_int(1)  = '1' else a(1);
  cy_int(2)  <= cy_int(1)  when  b_int(2)  = '1' else a(2);
  cy_int(3)  <= cy_int(2)  when  b_int(3)  = '1' else a(3);
  cy_int(4)  <= cy_int(3)  when  b_int(4)  = '1' else a(4);
  cy_int(5)  <= cy_int(4)  when  b_int(5)  = '1' else a(5);
  cy_int(6)  <= cy_int(5)  when  b_int(6)  = '1' else a(6);
  cy_int(7)  <= cy_int(6)  when  b_int(7)  = '1' else a(7);
  cy_int(8)  <= cy_int(7)  when  b_int(8)  = '1' else a(8);
  cy_int(9)  <= cy_int(8)  when  b_int(9)  = '1' else a(9);
  cy_int(10) <= cy_int(9)  when  b_int(10) = '1' else a(10);
  cy_int(11) <= cy_int(10) when  b_int(11) = '1' else a(11);
  cy_int(12) <= cy_int(11) when  b_int(12) = '1' else a(12);
  cy_int(13) <= cy_int(12) when  b_int(13) = '1' else a(13);
  cy_int(14) <= cy_int(13) when  b_int(14) = '1' else a(14);
  cy_int(15) <= cy_int(14) when  b_int(15) = '1' else a(15);
  
  c    <= (cy_int(14 downto 0) & cin_int) xor b_int;
  cout <= cy_int(15);
  ofl  <= cy_int(14) xor cy_int(15);
end Behavioral;
 

echo47

Advanced Member level 5
Joined
Apr 7, 2002
Messages
3,942
Helped
636
Reputation
1,270
Reaction score
88
Trophy points
1,328
Location
USA
Activity points
33,183
I don't know VHDL very well, so maybe this Verilog code will help you. Xilinx ISE 8.1 synthesized it with one 17-bit addsub in a Spartan-3.

Code:
module top (a, b, cin, op, c, cout, ofl);
  parameter             bits=16;
  input      [bits-1:0] a, b;
  input                 cin;
  input           [1:0] op;     // bit 1 enables cin, bit 0 selects ADD
  wire         [bits:0] cy = cin & op[1];
  output     [bits-1:0] c;
  output                cout, ofl;

  assign {cout,c} = op[0] ? {1'b0,a} + {1'b0,b} + cy : {1'b0,a} - {1'b0,b} - cy;
  assign ofl = cout ^ a[bits-1] ^ b[bits-1] ^ c[bits-1];
endmodule
I'm not sure if my ofl equation is correct. ISE used a LUT instead of the XOR built into the carry logic. Maybe there's a better way to do it.


Is there any way to instantiate a Xilinx ADSU16 library part? I'd like to compare my module to the ADSU16, but XST keeps giving me "ADSU16 not found" errors. The manual says ADSU16 is inferred, not instantiated, so maybe it's not possible.
 

nand_gates

Advanced Member level 3
Joined
Jul 19, 2004
Messages
892
Helped
174
Reputation
348
Reaction score
51
Trophy points
1,308
Activity points
6,803
All Xilinx Unified Library macros are treated as black boxes by the
synthesis tools. The implementation models for these components
is a NGO file. When Ngdbuild is run the NGO files are included
to properly implement the design.

The message "ADSU16 not found" can be safely ignored.
 

echo47

Advanced Member level 5
Joined
Apr 7, 2002
Messages
3,942
Helped
636
Reputation
1,270
Reaction score
88
Trophy points
1,328
Location
USA
Activity points
33,183
I can't ignore the error, XST complains and aborts:
ERROR:HDLCompilers:87 - "test.v" line 5 Could not find module/primitive 'ADSU16'

ModelSim also complains and aborts:
** Error: (vsim-3033) test.v(5): Instantiation of 'ADSU16' failed. The design unit was not found.

Test code:
Code:
module top (a, b, s);
  input      [15:0] a, b;
  output     [15:0] s;

  ADSU16 u1 (.A(a), .B(b), .S(s));
endmodule
Most other Xilinx library design elements work fine, but not that one.
 

nand_gates

Advanced Member level 3
Joined
Jul 19, 2004
Messages
892
Helped
174
Reputation
348
Reaction score
51
Trophy points
1,308
Activity points
6,803
OK I got the problem!
For HDL, ADSU16 is inferred rather than instantiated. If you are working with
schematics only then you can instantiated ADSU16!

The code below will do this .....
Plaese refer to http://toolbox.xilinx.com/docsan/xilinx5/data/docs/lib/lib0056_40.html
Code:
module addsub16 (add, a, b, ci, sum, co, v);
   input add, ci;
   input [15:0] a, b;
   output [15:0] sum;
   output      co;
   output      v;
   
   reg [15:0]  sum;
   reg v, co;
   reg         co_int, junk;
   
   always @(a or b or add or ci) begin
	  if (add) begin
		 {co_int,sum,junk} = {a,ci} + {b,1'b1};
		 co = co_int;
	  end else begin
		 {co_int,sum,junk} = {a,ci} - {b,1'b1};
		 co = ~co_int;
	  end
	  v = co_int ^ sum[15] ^ a[15] ^ b[15];
   end // always @ (a or b or add or ci)
endmodule
 

echo47

Advanced Member level 5
Joined
Apr 7, 2002
Messages
3,942
Helped
636
Reputation
1,270
Reaction score
88
Trophy points
1,328
Location
USA
Activity points
33,183
Did you try that? ISE 7.1.04i and 8.1.01i both create a 17-bit adder, a 18-bit subtractor, and a row of LUTs (probably a mux). There's nothing logically wrong with the code, XST simply doesn't recognize the addsub.

My example creates a 17-bit addsub.

Of course, the results could reverse with the next version if ISE.
 

nand_gates

Advanced Member level 3
Joined
Jul 19, 2004
Messages
892
Helped
174
Reputation
348
Reaction score
51
Trophy points
1,308
Activity points
6,803
Yes you are right echo47!!
I think we need to do something like this .....
here I translated ADSU16 schematics!!
l
Code:
ibrary IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity alu is
    Port ( a : in std_logic_vector(15 downto 0);
           b : in std_logic_vector(15 downto 0);
           cin : in std_logic;
           op : in std_logic_vector(1 downto 0);
           c : out std_logic_vector(15 downto 0);
           cout : out std_logic;
           ofl : out std_logic);
end alu;

architecture Behavioral of alu is
  component MUXCY_D
   port (LO : out STD_ULOGIC;
         O  : out STD_ULOGIC;
         CI : in STD_ULOGIC;
         DI : in STD_ULOGIC;
         S  : in STD_ULOGIC);
  end component;
  
  component MUXCY_L
    port (LO : out STD_ULOGIC;
          CI : in STD_ULOGIC;
          DI : in STD_ULOGIC;
          S  : in STD_ULOGIC);
  end component;

  component MUXCY
    port (O : out STD_ULOGIC;
          CI : in STD_ULOGIC;
          DI : in STD_ULOGIC;
          S : in STD_ULOGIC);
  end component;
  
  signal b_int : std_logic_vector(15 downto 0);
  signal cy_int : std_logic_vector(15 downto 0);
  signal cy_int_14 : std_logic;
  signal cin_int : std_logic;
begin
  cin_int <= op(1) and cin;
  b_int <= a xor b xor (op(0)&op(0)&op(0)&op(0)&op(0)&op(0)&op(0)&op(0)&op(0)&op(0)&op(0)&op(0)&op(0)&op(0)&op(0)&op(0));

  MUXCY_L_0 : MUXCY_L port map (  cy_int(0)  , cin_int    ,  a(0) ,  b_int(0));   
  MUXCY_L_1 : MUXCY_L port map (  cy_int(1)  , cy_int(0)  ,  a(1) ,  b_int(1));   
  MUXCY_L_2 : MUXCY_L port map (  cy_int(2)  , cy_int(1)  ,  a(2) ,  b_int(2));   
  MUXCY_L_3 : MUXCY_L port map (  cy_int(3)  , cy_int(2)  ,  a(3) ,  b_int(3));   
  MUXCY_L_4 : MUXCY_L port map (  cy_int(4)  , cy_int(3)  ,  a(4) ,  b_int(4));   
  MUXCY_L_5 : MUXCY_L port map (  cy_int(5)  , cy_int(4)  ,  a(5) ,  b_int(5));   
  MUXCY_L_6 : MUXCY_L port map (  cy_int(6)  , cy_int(5)  ,  a(6) ,  b_int(6));   
  MUXCY_L_7 : MUXCY_L port map (  cy_int(7)  , cy_int(6)  ,  a(7) ,  b_int(7));   
  MUXCY_L_8 : MUXCY_L port map (  cy_int(8)  , cy_int(7)  ,  a(8) ,  b_int(8));   
  MUXCY_L_9 : MUXCY_L port map (  cy_int(9)  , cy_int(8)  ,  a(9) ,  b_int(9));   
  MUXCY_L_10 : MUXCY_L port map (  cy_int(10) , cy_int(9)  ,  a(10), b_int(10));  
  MUXCY_L_11 : MUXCY_L port map (  cy_int(11) , cy_int(10) ,  a(11), b_int(11));  
  MUXCY_L_12 : MUXCY_L port map (  cy_int(12) , cy_int(11) ,  a(12), b_int(12));  
  MUXCY_L_13 : MUXCY_L port map (  cy_int(13) , cy_int(12) ,  a(13), b_int(13));
  MUXCY_D_14 : MUXCY_D port map (cy_int(14), cy_int_14 ,cy_int(13) , a(14),  b_int(14));
  MUXCY_15 : MUXCY port map (cy_int(15), cy_int(14), a(15),  b_int(15));
  
  c    <= (cy_int(14 downto 0) & cin_int) xor b_int;
  cout <= cy_int(15);
  ofl  <= cy_int_14 xor cy_int(15);
end Behavioral;
 

umairsiddiqui

Full Member level 2
Joined
Apr 13, 2004
Messages
144
Helped
7
Reputation
14
Reaction score
1
Trophy points
1,298
Location
Sweden
Activity points
1,436
so to force-fully instantiate adsu16 we have no option except, add a schematic file into project, put the adsu16 symbol and io ports. generate functional hdl and instatiation template....??????

a macro is usable for schematic entry but not hdl entry...very clumsy decision by xilinx

but haven't considered the FMAPs, RLOC and HU_SET contraints in adsu16, how can we use these contraints to optimize the placement?
 

echo47

Advanced Member level 5
Joined
Apr 7, 2002
Messages
3,942
Helped
636
Reputation
1,270
Reaction score
88
Trophy points
1,328
Location
USA
Activity points
33,183
That's true, but it's also true for AND16, SUB16, CC16CLE, and many other old library devices. Normally you just let the compiler infer arithmetic, counters, etc, because the synthesizer usually does nice optimization. (However, we've seen that it's a little twitchy with addsub when using carry and overflow.) The only reason I wanted to instantiate the ADSU16 was to compare it's behavior to my example code.

If you want to constrain the inferred addsub, you could put its code into a new module, and then constrain the module.
 

Status
Not open for further replies.
Toggle Sidebar

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Top