Thông báo

Collapse
No announcement yet.

[HELP] Thiết kế mạch nhân bằng VHDL! (phép nhân có dấu và Booth Algorithm) !!!

Collapse
X
 
  • Lọc
  • Giờ
  • Show
Clear All
new posts

  • [HELP] Thiết kế mạch nhân bằng VHDL! (phép nhân có dấu và Booth Algorithm) !!!

    Project:
    Thiết kế mạch nhân: nhân 2 số 8 bit có dấu cho kết quả 16-bit
    Số âm được biểu diễn ở dạng bù 2
    Phương pháp:
    + Lấy bù 1 của số nhân và số bị nhân nếu chúng là số âm
    + Nhân 2 số dương và lấy bù của tích nếu cần thiết
    Pre-laboratory:

    Trước đó mình đã có làm qua về thiết kế mạch nhân, nhưng chỉ dùng 2 số ko dấu 4-bit- dùng phương pháp dịch và cộng. Nay chuyển sang dùng có dấu thì bị vấn đề trong việc chuyển đổi bù 2, làm sao phân biệt số nhân và số bị nhân trong trường hợp nó âm. Bởi vì có đến 4 trường hợp để mà xét, mình chỉ mới học VHDL nên kĩ thuật lập trình còn ‘non’, nên không thể trình bày ý tưởng bằng lập trình, mong anh em giúp đỡ.

    Last project: Thiết kế mạch nhân 2 số 4-bit không dấu
    Diagram như sau: (do thầy đưa) – mình cũng băn khoăn chỗ này, thường thường phương pháp dịch bit và cộng thì mình phải dịch trái, sao đằng này lại dịch phải


    Trong đó:
    Ad – Add signal // ngõ ra của bộ 4-bit Adder được lưu trữ trong ACC (Accumulator)
    Sh – Shift signal // shift 9-bit ACC sang bên phải (mình còn thắc mắc tại sao chỗ này ông thầy lại dùng 9 bit mà không phải 8-bit, 4-bit x 4-bit  product phải 8-bit mới đúng)
    Ld – Load signal // load số bị nhân (multiplier) vào 4-bit thấp của bộ ACC và clear 5-bit trên
    State Diagram:


    FSM:
    Trong đó:
    M là bit 0 của ACC (thông qua việc kiểm tra bit cuối của ACC mà ta tiến hành dịch bit hay là cộng)

    CODE VHDL:
    library IEEE;
    use IEEE.std_logic_1164.all;
    use IEEE.std_logic_unsigned.all;
    use IEEE.numeric_bit.all;

    entity mult4X4 is
    port (Clk, St : in std_logic;
    Mplier,Mcand : in std_logic_vector(3 downto 0);
    Done : out std_logic;
    result : out std_logic_vector(7 downto 0));
    end mult4X4;

    architecture behave1 of mult4X4 is
    signal State : integer range 0 to 9;
    signal ACC : std_logic_vector(8 downto 0); --accumulator
    alias M : std_logic is ACC(0); --M la bit 0 cua ACC
    begin
    process
    begin
    wait until Clk = '1'; --thuc hien o canh len cua xung clk
    case State is
    when 0=> --State ban dau
    if St='1' then
    ACC(8 downto 4) <= "00000"; --clear 5-bit tren cua ACC
    ACC(3 downto 0) <= Mplier; --load multiplier vao 4-bit duoi ACC
    State <= 1;
    end if;
    when 1 | 3 | 5 | 7 => --"add/shift" State
    if M = '1' then --Add multiplicand
    ACC(8 downto 4) <= ('0'&ACC(7 downto 4)) + ('0'&Mcand);
    State <= State+1;
    else
    ACC <= '0' & ACC(8 downto 1); --Shift ACC sang ben phai
    State <= State + 2;
    end if;
    when 2 | 4 | 6 | 8 => --"shift" State
    ACC <= '0' & ACC(8 downto 1); --shift sang bên ph?i
    State <= State + 1;
    when 9 =>
    State <= 0;
    end case;
    end process;
    Done <= '1' when State = 9 else '0';
    result <= ACC (7 downto 0) when state = 9 else "00000000";
    end behave1;
    Anh em có thể giúp mình ý tưởng phép nhân có dấu được không?
    Mới được bổ sung thêm cái block diagram



  • #2
    Chào bạn Pi_happy,

    Thật ra viết mạch nhân bằng RTL code rất đơn giản không cần phải mô tả chi tiết như bạn làm gì. Các phần mềm EDA hiện nay rất mạnh đủ sức tự tổng hợp mạch nhân giúp bạn. Ngoài ra mạch nhân theo kiểu cộng dịch này hiện nay không còn ai sử dụng nữa rồi vì tốc độ của nó quá chậm, và thật sự hiện nay người thiết kế rất hiếm khi bị giới hạn về mặt diện tích chip. Tớ viết một đoạn code Verilog ở đây để bạn tham khảo (tớ lâu không sử dụng VHDL nên bây giờ quên gần hết rồi, xem ra ở VN mọi người chuộng VHDL hơn Verilog thì phải).

    Code:
    module multiplier(A, B, Y);
    parameter width=8;
    input [width-1:0] A, B;
    output [2*width-1:0] Y;
    
    integer Ai, Bi, Yi;
    
    always @ (A or B)
    begin
    Ai=A;
    Bi=B;
    Yi=Ai*Bi;
    end
    
    assign Y=Yi;
    endmodule
    Bạn có thể thấy trong cách viết trên tớ tạo ra 2 biến Ai, Bi, là kiểu có dấu, và 2 biến này lấy giá trị từ 2 biến đầu vào A, B là kiểu không dấu. Mạch nhân bên trong được thực hiện với các biến là loại có dấu, sau đó đầu ra lại được chuyển từ Yi là kiểu có dấu sang kiểu không dấu là Y. Mạch nhân đơn giản chỉ cần viết "*".

    Mạch ghi dịch mà thầy bạn cho bạn là mạch chuẩn mà mọi người vẫn thường dùng trong thiết kế công nghiệp đó bạn. Bạn thực hiện phép dịch trái, rồi cộng vào kết quả chỉ là cách tính toán trên giấy thôi. Mạch này có ưu điểm là 8 flipflop kết quả có thể dùng chung cho số nhân nên tiết kiệm được flipflop nhưng hiện này chẳng còn ai sử dụng nữa. Còn mạch booth multiplier là mạch nhân tốc độ cao. Ở đây có sẵn code tớ chẳng cần viết nữa.

    http://hdlsnippets.com/verilog_booth_multiplier

    Comment


    • #3
      Mạch nhân Booth (kèm VHDL code)

      Okie, Hôm nay đưa cái file project mà mình viết code VHDL cho anh em trên diễn đàn luôn!!! Mong rằng sẽ giúp ích được anh em nào trong lúc học môn VHDL thì có cái để mà tham khảo

      Project: (Mình để nguyên văn tiếng Anh luôn, do trình TA còn 'non', nếu mà dịch sai nghĩa thì mất công )

      Thiết kế mạch nhân Booth và simulate nhân 2 số có dấu.

      Requirement:
      - Assume each number is n bits. Use an (n + 1) –bit register for the accumulator (A) so the sign bit will not be lost is an overflow occurs. Also, use an (n + 1)-bit register to hold the multiplier and an n-bit register (C) to hold the multiplicand
      Method:
      1. Clear A ( the accumulator), load into the upper n bits of B, clear B0, and load the multiplicand into C.
      2. Test the lower two bits of B (B1 B0).
      a. If B1 B0 = 01 , then add C to A ( C should be the sign-extended to n + 1 bits and added to A using an (n + 1)– bit adder).
      b. If B1 B0 = 10 , then add the twos complement of C to A
      c. If B1 B0 = 11 or 00 skip this step
      3 Shift A and B right one place with sign extended
      4. Repeat steps 2 and 3 , n-1 more times
      5. Product will be in A and B , ignore B0



      - Mình thiết kế bộ nhân 2 số 8-bit nên sử dụng 9-bit register cho A và B, 9-bit Full Adder, 8-bit complementer, 4-bit counter (thực ra có thể dùng 3 bit thôi do 8-bit thì chỉ cần dùng 2^3 là đủ rồi, nhưng khi mình chạy thử thì nó báo kết quả sai, nên đành tăng bit lên cho nó thôi) và 1 bộ Control




      Code:
      library IEEE;
      use IEEE.numeric_bit.all;
      use IEEE.std_logic_1164.all;
      use IEEE.std_logic_signed.all;
      
      entity part2 is
        port(Clk, St		: in std_logic;
             Mplier, Mcand	: in std_logic_vector(7 downto 0);
             Result		: out std_logic_vector(15 downto 0);
             Done		: out std_logic);
      end part2;
      
      architecture Behavioral of part2 is
      
      signal State		: integer range 0 to 4;
      signal counter		: std_logic_vector(3 downto 0);
      signal A, B			: std_logic_vector(8 downto 0);
      signal C				: std_logic_vector(7 downto 0);
      signal M			: std_logic_vector(1 downto 0) ;
      
      begin
      
       M <= B(1)&B(0) ;
       process(Clk,St,Mplier,Mcand)
       begin
      
         if (Clk = '1') and Clk'event then
      	case State is 
      		when 0 =>  
      			if St = '1' then 
      				A <= "000000000";                                          
      				B <= Mplier & '0' ;
      				C <= Mcand ;
      			end if;
      				State <= 1;
      				counter <= "0000" ;
              
      	  
       when 1  =>  
               if M = "01" then 
      				A <= A + (C(7)&C) ;
      	  State <= 2 ;
              elsif M = "10" then 
                    A <= A + not(C(7)& C) + 1 ; 
      					State <= 2 ;
              else 	State <= 2 ;
              end if ;
      			 
      when 2  =>
                  B <= A(0) & B(8 downto 1);
                  A <= A(8) & A(8 downto 1);
                  counter <= counter + 1 ;
      			State <= 3;
      when 3 =>
              if counter = "1000" then  
      			Result <= A(7 downto 0)&B(8 downto 1) ;
      			state <= 4;
      		  else State <= 1 ;
              end if ;				
      when 4  => state <= 0;
      		
             end case;
           end if;
         end process;
      	
          Done <= '1' when State = 4 else '0';
      end Behavioral;

      Testbench: (Mình dùng Xilinx ISE ver 12.4)
      Check thử các kết quả sau:

      01100110 x 00110011 = 102 x 51 = 5202

      10100110 x 01100110 = (-90) x 102 = -9180

      01101011 x 10001110 = 107 x (-114) = -12198

      11001100 x 10011001 = (-102) x (-53) = 5356




      Code:
      LIBRARY ieee;
      USE ieee.std_logic_1164.ALL;
       
      -- Uncomment the following library declaration if using
      -- arithmetic functions with Signed or Unsigned values
      --USE ieee.numeric_std.ALL;
       
      ENTITY test IS
      END test;
       
      ARCHITECTURE behavior OF test IS 
       
          -- Component Declaration for the Unit Under Test (UUT)
       
          COMPONENT part2
          PORT(
               Clk : IN  std_logic;
               St : IN  std_logic;
               Mplier : IN  std_logic_vector(7 downto 0);
               Mcand : IN  std_logic_vector(7 downto 0);
               Result : OUT  std_logic_vector(15 downto 0);
               Done : OUT  std_logic
              );
          END COMPONENT;
          
      
         --Inputs
         signal Clk : std_logic := '0';
         signal St : std_logic := '0';
         signal Mplier : std_logic_vector(7 downto 0) := (others => '0');
         signal Mcand : std_logic_vector(7 downto 0) := (others => '0');
      
       	--Outputs
         signal Result : std_logic_vector(15 downto 0);
         signal Done : std_logic;
      
         -- Clock period definitions
         constant Clk_period : time := 10 ns;
       
      BEGIN
       
      	-- Instantiate the Unit Under Test (UUT)
         uut: part2 PORT MAP (
                Clk => Clk,
                St => St,
                Mplier => Mplier,
                Mcand => Mcand,
                Result => Result,
                Done => Done
              );
      
         -- Clock process definitions
         Clk_process :process
         begin
      		Clk <= '0';
      		wait for Clk_period/2;
      		Clk <= '1';
      		wait for Clk_period/2;
         end process;
       
      
         -- Stimulus process
         		
           stim_proc:process
      	begin
      	-------------TEST1 ------------
      	St <= '1'; 
      	Mcand 	<= "01100110";	-- 102
      	Mplier 	<= "00110011"; -- 51 x 102 = 5202
      	wait for 12 ns; 
      	St <= '0';
      	wait until Done = '1';
      	wait for 20 ns; 
      	-------------TEST2 ------------
      	St <= '1';
      	Mcand 	<= "10100110";	 -- -90
      	Mplier 	<= "01100110";  -- 102x (-90) = -9180 
      	wait for 12 ns; 
      	St <= '0'; 
      	wait until Done = '1';
      	wait for 20 ns; 
      
      	-------------TEST3 ------------
      	St <= '1';
      	Mcand 	<= "01101011";	--107
      	Mplier 	<= "10001110"; -- (-114)x107 = -12198
      	wait for 12 ns; 
      	St <= '0'; 
      	wait until Done = '1';
      	wait for 20 ns; 
      
      	-------------TEST4 ------------
      	St <= '1'; 	
      	Mcand 	<= "11001100"; -- -103
      	Mplier 	<= "10011001"; -- -52x(-103) = 5356
      	wait for 12 ns; 
      	St <= '0'; 
      	wait until Done = '1';
      	wait for 30 ns; 
      
      	------------------------------
            wait;
         end process;
      END;

      Comment


      • #4
        Thiết kế và kiểm tra khối nhân số nguyên không dấu 8x8 = 8 bit, với đầuvào và đầu ra có định dạng là số thực dấu phẩy tĩnh8 bít trong đó phần nguyên và phần thập phân mỗi phần biểu diễn 4 bit.Yêu cầu làm tròn theo số gần nhất chẵn, có báo tràn. Kiểm tra kết quả trên mạch FPGA.
        bài này làm thế nào các pro

        Comment


        • #5
          Nguyên văn bởi anhhuyvt3 Xem bài viết
          Thiết kế và kiểm tra khối nhân số nguyên không dấu 8x8 = 8 bit, với đầuvào và đầu ra có định dạng là số thực dấu phẩy tĩnh8 bít trong đó phần nguyên và phần thập phân mỗi phần biểu diễn 4 bit.Yêu cầu làm tròn theo số gần nhất chẵn, có báo tràn. Kiểm tra kết quả trên mạch FPGA.
          bài này làm thế nào các pro
          Cậu học ở HVKTQS đúng không?

          Comment


          • #6
            vâng đúng ùi ạ

            Comment


            • #7
              Nguyên văn bởi anhhuyvt3 Xem bài viết
              vâng đúng ùi ạ
              Hình như đây là bài tập môn học, bạn nên lên gặp Thầy để các Thầy hướng dẫn rồi sau đó về thực hiện, đoạn nào mắc thì hỏi Thầy, hỏi bạn hoặc đưa lên đây để cùng giải quyết thắc mắc để hoàn thiện bài tập môn học của mình.
              Chúc bạn hoàn thành tốt bài tập

              Comment

              Về tác giả

              Collapse

              pi_happy Tìm hiểu thêm về pi_happy

              Bài viết mới nhất

              Collapse

              Đang tải...
              X