Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics 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.

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

Status
Not open for further replies.

umairsiddiqui

Full Member level 2
Joined
Apr 13, 2004
Messages
143
Helped
7
Reputation
14
Reaction score
1
Trophy points
1,298
Location
Sweden
Activity points
1,434
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;
 

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;
 
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.
 
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.
 

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.
 

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 **broken link removed**
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
 

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.
 

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;
 

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?
 

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.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top