Thông báo

Collapse
No announcement yet.

[HELP] VHDL - Khối chia không phục hồi phần dư !

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

  • [HELP] VHDL - Khối chia không phục hồi phần dư !



    đây à sơ đồ khối và thuật toán bài của em, em đang gặp vướng mắc trong việc đồng bộ các tín hiệu với xung clk,liệu sau mỗi xung thì các khối con có làm việc cùng 1 lúc ko ạ,hay là nó sẽ làm việc lần lượt ?
    trong phần code của em làm,em có cho thêm 1 bộ đếm counter để cho vào bộ mux trong khối thanh ghi remainer (chọn tín hiệu vào từ ngoài hay từ bộ dịch ở trên xuống) ,và thêm nữa là counter có chức năng dừng dịch sau khi quoiter đã đủ bit,nói thế này chắc cũng ko hình dung đc bài của em,thôi thì các bác nhìn tạm sơ đồ khối vậy.
    Em làm xong code rồi,nhưng kết quả ra sai,mong mọi ng ai hiểu hoặc đã làm rồi giúp em.

    Khối chia không phục hồi phần dư.....
    Code:
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.STD_LOGIC_ARITH.ALL;
    use IEEE.STD_LOGIC_UNSIGNED.ALL;
    use IEEE.numeric_std.all;
    use IEEE.numeric_bit.all;
    --------------------------------
    entity  divider is
    port (
    	sobichia :in std_logic_vector (7 downto 0);
    	sochia	 :in std_logic_vector (3 downto 0);
    	
    	WE		: in std_logic;
    	clk		: in std_logic;
    	reset 	: in std_logic;
    	
    	thuong : out std_logic_vector (4 downto 0);
    	du		: out std_logic_vector(4 downto 0)
    	);
    	end entity;
    ---------------------------------------
    architecture behavioral of divider is
    signal reg1out : std_logic;
    signal coutS :std_logic;
    signal b0:std_logic_vector(4 downto 0);
    signal a0:std_logic_vector(4 downto 0);
    signal Sout :std_logic_vector(4 downto 0);
    signal thuong1 :std_logic_vector(4 downto 0);
    ------------------------------------------
    signal     	cnt_reset :  std_logic; 
    signal   	temp  : std_logic;
    signal cnt :std_logic_vector(2 downto 0);
    signal   	shift_enable : std_logic;
    signal reg_temp:std_logic;
    --------------------------------------
    component reg_q is
        port(
    	bitin : in std_logic;
        Q     : out std_logic_vector(4 downto 0);
        CLK   : in  std_logic;
        WE : in  std_logic    ;
    	 RESET : in  std_logic
        );
    end component;
    component remainder is
        port(
            clk          : in std_logic;
            reset        : in std_logic;
            WE           : in std_logic;
    		sh_e		 : in std_logic;
            Din_S        : in std_logic_vector ( 4 downto 0 );
            Din_8          : in std_logic_vector ( 7 downto 0 ) ;
    		
    		Dout         : out std_logic_vector(4 downto 0)    
       
    	);
    end component;
    component reg1 is
    port(
        D     : in  std_logic; 
        Q     : out std_logic;
        CLK   : in  std_logic;
        RESET : in  std_logic    
        ); 
    end component;
    
    component adder is 
    	port ( 
    		a : in std_logic_vector ( 4 downto 0);
    		b : in std_logic_vector ( 4 downto 0);
    		cout : out std_logic;
    		sum : out std_logic_vector (4 downto 0)
    	);
    end component;
    
    component mux5 is
    	port (
    		din1 : in std_logic_vector ( 3 downto 0);
    		sub : in std_logic ;
    		mux_out : out std_logic_vector ( 4 downto 0 ) 
    	);
    	
    end component ; 
    component counter IS
        PORT(
            clk            : in  std_logic; 
            reset          : in  std_logic; 
            counter_enable : in  std_logic; 
            cnt            : out std_logic_vector(2 DOWNTO 0)
            );
    END component;
    begin
    cnt_reset <= WE or reset;
    ct1: component counter
                        port map ( counter_enable=> shift_enable,reset=>cnt_reset,cnt=>cnt,clk=>clk);
    
    with cnt select
    temp <= '1' when "100",
    '0' when others;
    mux5_1:component mux5 
    					port map (din1=>sochia ,sub=>reg1out,mux_out=> b0 );
    add:component adder 
    					port map (a=>a0 ,b=>b0 ,cout=>coutS ,sum=>Sout );
    reg_1:component reg1
    					port map(D=>coutS ,Q=>reg1out ,clk=>clk,reset=>reset);
    remainder1 : component remainder
                        port map (Din_S => Sout, reset => reset, Din_8 => sobichia,Dout=>a0,clk=>clk,WE=>WE,sh_e=>shift_enable);					
    reg_q1 : component reg_q
                        port map (bitin=>reg1out, Q =>thuong1,CLK=>clk,WE => WE	,reset=>reset); 
    sreg2:component reg1
                        port map (d=>temp,clk =>clk,reset =>reset,Q =>reg_temp);	
     shift_enable<= not reg_temp;
     du<=a0;
     thuong<=thuong1;
     end behavioral;
    đây là code phần quoiter
    Code:
    -----------------------------------------
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    -----------------------------------------
    entity reg_q is
    port(
    	bitin : in std_logic;
     	WE: in std_logic;
        Q     : out std_logic_vector(4 downto 0);
        CLK   : in  std_logic;
        RESET : in  std_logic    
        ); 
    end reg_q;
    ------------------------------------------
    architecture behavioral of reg_q is
    SIGNAL D1 : std_logic_vector(4 downto 0);
    begin
        reg_p: process (CLK,bitin, RESET)
        begin
           if RESET = '1' then 
                D1 <= (others => '0');
            elsif CLK = '1' and CLK'event then
                D1 <= D1(3 downto 0)& bitin;
            end if;
        end process reg_p;
    	Q<=D1;
    end behavioral;
    ------------------------------------------
    Khối test : chỗ này em băn khoăn về cái process,cứ cho we với reset khác nhau lại ra kq khác ..
    Code:
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.STD_LOGIC_ARITH.ALL;
    use IEEE.STD_LOGIC_UNSIGNED.ALL;
    use IEEE.numeric_std.all;
    use IEEE.numeric_bit.all;
    --------------------------------
    entity  test is
    	end entity;
    -----------------------
    architecture tester of test is
    component divider is
    port (
    	sobichia :in std_logic_vector (7 downto 0);
    	sochia	 :in std_logic_vector (3 downto 0);
    	
    	WE		: in std_logic;
    	clk		: in std_logic;
    	reset 	: in std_logic;
    	
    	thuong : out std_logic_vector (4 downto 0);
    	du		: out std_logic_vector(4 downto 0)
    	);
    end component;
    ------------------
    signal	sobichia : std_logic_vector (7 downto 0):="10000101";
    signal	sochia	 : std_logic_vector (3 downto 0):="1110";
    
    signal	we		: std_logic:='0';
    signal	clk		: std_logic:='1';
    signal	reset 	: std_logic:='1';
    
    signal	thuong :   std_logic_vector (4 downto 0);
    signal	du		:  std_logic_vector(4 downto 0);
    --create clock
    begin
    DUT: component divider
    port map (sobichia ,sochia,we,clk,reset,thuong,du);
    
    create_clock: process
    begin
    wait for 2 ns;
    CLK <= not CLK after 50 ns;
    end process create_clock;
    -----------------------------
    create_reset: process
    begin
    --wait for 150 ns;
    --reset <= '1';
    wait for 50 ns;
    reset <= '0';
    --WE <= '1';
    wait for 100 ns;
    WE <= '1';
    
    wait;
    end process create_reset;
    end tester;
    ----------------------------
    các khối con hơi dài nên em không tiện đưa lên,hic..
    đây là kq mô phỏng :

    em bị sai kết quả thương và dư ...

    cảm ơn các bác trước ạ .

  • #2
    Có vẻ bạn làm đúng hướng. Để check sự đồng bộ giữa các tín hiệu, bạn nên vẽ waveform ra giấy, để chắc là bạn code đúng như ý muốn.Công cụ vẽ waveform đẹp và free: www.timingtool.com

    Comment


    • #3
      Bạn có thể vẽ các waveform như hình dưới, trước khi code để xem giải thuật có đúng không. Các khối hoạt động cùng lúc.
      Click image for larger version

Name:	simdiv.png
Views:	1
Size:	12.4 KB
ID:	1347481

      Comment


      • #4
        quả thực mình chưa hình dung được các khối hoạt động theo xung clk ra sao,vì vậy mình nghĩ lỗi sai của mình nằm ở phần đồng bộ xung giữa các khối.
        mình cũng chỉ được học qua nên cũng hơi thiếu kiến thức về vấn đề này,xin bạn chỉ giùm

        Comment


        • #5
          Sao mình làm bằng tay thuật toán ko được nhỉ. Bạn làm thử thành cái bảng
          __________________________________________________
          Chu kì | opa | opb | remainder | quotient | cout | cout_delay|
          1..
          2
          3

          Comment


          • #6
            thuật toán thì cũng đơn giản thôi bạn.

            đầu tiên thêm bit dấu vào số bị chia S(0) - dấu dương = 0
            lấy 5 bit đầu của số bị chia + với bù 2 của số chia.

            sau phép cộng,kết quả bit tràn được lưu vào thanh ghi 1 bit,quay lại vào khối mux để chỉ thị xem nhập giá trị 2^4d hay bù 2 của 2^4d vào bộ cộng ,khi đó phần Sum sau khi cộng sẽ được dịch sang trái 1 bit,và 5 bit đầu của Sum đó lại quay trở về bộ cộng để cộng tiếp.
            Cứ thế cho đến lúc thanh ghi thương điền đầy 5 bit....
            mong bạn giúp đỡ

            Comment


            • #7
              Nguyên văn bởi gaconst Xem bài viết
              thuật toán thì cũng đơn giản thôi bạn.

              đầu tiên thêm bit dấu vào số bị chia S(0) - dấu dương = 0
              lấy 5 bit đầu của số bị chia + với bù 2 của số chia.

              sau phép cộng,kết quả bit tràn được lưu vào thanh ghi 1 bit,quay lại vào khối mux để chỉ thị xem nhập giá trị 2^4d hay bù 2 của 2^4d vào bộ cộng ,khi đó phần Sum sau khi cộng sẽ được dịch sang trái 1 bit,và 5 bit đầu của Sum đó lại quay trở về bộ cộng để cộng tiếp.
              Cứ thế cho đến lúc thanh ghi thương điền đầy 5 bit....
              mong bạn giúp đỡ
              Tất cả mọi khối trên hình trên phải hoạt động trong cùng một xung clock. Cần 5 xung clock để làm xong tính chia ở trên. Bạn có thể dùng bộ đếm để xác định khi nào nhận đường vào mới và khi nào thì cộng việc chia đã hoàn tất.

              Code ở trên không có đủ chi tiết nên tôi không biết lỗi ở đâu nhưng hy vọng bạn có thể tìm ra. Chúc may mắn
              Chúc một ngày vui vẻ
              Tony
              email : dientu_vip@yahoo.com

              Comment


              • #8
                @gaconst,
                Tôi viết C code để xác nghiệm độ hoạt động trước rồi dùng nó để viết VHDL. Bạn thí nghiệm lại xem nó có theo ý muốn của bạn không.

                Code:
                 C code
                #include <iostream>
                #define LOW 16
                #define HIGH 32
                using namespace std;
                
                int main()
                {
                	bool sec_sel = 1; //
                	unsigned int d = 14;
                	unsigned int z = 133;
                	
                	unsigned int sh, sl, dt, sum;
                	unsigned int dn = HIGH-d;
                
                	for (int i=0; i< 5; i++)
                	{
                		sh = z/LOW;
                		sl = z%LOW;
                		if (sec_sel)
                			dt = dn;
                		else
                			dt = d;
                		sum = sh + dt;
                		if (sum >= HIGH)
                			sum -= HIGH;
                		if (sum >= LOW)
                			sec_sel = 0;
                		else
                			sec_sel = 1;
                		z = ((sum*LOW)+sl)*2;
                		if (z > LOW*HIGH)
                			z-=LOW*HIGH;
                		cout << "sh = " << sh << "; sl = " << sl << "; sum = " << sum << "; z = " << z << "; result = " << sec_sel << endl;
                	}
                	return 0;
                }
                Code:
                 VHDL code
                library IEEE;
                use IEEE.STD_LOGIC_1164.ALL;
                use IEEE.STD_LOGIC_ARITH.ALL;
                use IEEE.STD_LOGIC_UNSIGNED.ALL;
                use IEEE.numeric_std.all;
                use IEEE.numeric_bit.all;
                --------------------------------
                entity  divider is
                port (
                	sobichia :in std_logic_vector (7 downto 0); -- z
                	sochia	 :in std_logic_vector (3 downto 0); -- d
                	
                	clk		: in std_logic;
                	reset 	: in std_logic;
                	
                	--du		: out std_logic_vector(4 downto 0);
                	thuong : out std_logic_vector (4 downto 0)
                	);
                	end entity;
                ---------------------------------------
                architecture behavioral of divider is
                signal z, z_reg : std_logic_vector(8 downto 0);
                signal sec_sel, sec_sel_reg :std_logic;
                signal count : integer range 0 to 7;
                signal dn : std_logic_vector(4 downto 0);
                signal thuong_t, thuong_reg, thuong_d, thuong_out : std_logic_vector(4 downto 0);
                begin
                	dn <= (not ('0'&sochia))+'1';
                process (sec_sel_reg, z_reg, dn, sochia, thuong_reg, count)
                	variable sh : std_logic_vector(4 downto 0);
                	variable sl : std_logic_vector(3 downto 0);
                	variable dt : std_logic_vector(4 downto 0);
                	variable sum : std_logic_vector(5 downto 0);
                	variable zt, z_i : std_logic_vector(8 downto 0);
                	variable sec_sel_i : std_logic;
                	variable thuong_i : std_logic_vector(4 downto 0);
                begin
                	if (count = 0) then
                		sec_sel_i := '1';
                		z_i := '0'&sobichia;
                		thuong_i := (others => '0');
                		thuong_d <= thuong_reg;
                	else
                		sec_sel_i := sec_sel_reg;
                		z_i := z_reg;
                		thuong_i := thuong_reg;
                		thuong_d <= thuong_out;		
                	end if;
                	sh := z_i(8 downto 4);
                	sl := z_i(3 downto 0);
                	if (sec_sel_i = '1') then
                		dt := dn;
                	else
                		dt := '0'&sochia;
                	end if;
                	sum := ('0'&sh)+('0'&dt);
                	zt := sum(4 downto 0) & sl;
                	z <= zt(7 downto 0)&'0';
                	sec_sel <= sum(5);
                	thuong_t <= thuong_i(3 downto 0)&sum(5);
                end process;
                
                process (clk, reset)
                begin
                	if (reset = '1') then
                		count <= 0;
                		sec_sel_reg <= '1';
                		z_reg <= (others => '0');
                		thuong_reg <= (others => '0');
                		thuong_out <= (others => '0');
                	elsif (clk'event and clk = '1') then
                		sec_sel_reg <= sec_sel;
                		z_reg <= z;
                		thuong_reg <= thuong_t;
                		thuong_out <= thuong_d;
                		if (count = 4) then
                			count <= 0;
                		else
                			count <= count + 1;
                		end if;
                	end if;
                end process;
                   thuong <= thuong_out;
                
                end behavioral;
                Chúc một ngày vui vẻ
                Tony
                email : dientu_vip@yahoo.com

                Comment


                • #9
                  đây là bài chia số 2kbit cho số k bít. Nhưng nếu chia số k bit cho số k bit thì thuật toán của nó như thế nào nhỉ?

                  Comment


                  • #10
                    các pro cho e hỏi về khối chia số nguyên có dấu kbit/kbit= kbit
                    đang làm cái đề tài mà chưa được

                    Comment


                    • #11
                      các pro cho e hỏi về khối chia số nguyên có dấu kbit/kbit= kbit
                      đang làm cái đề tài mà chưa được

                      Comment


                      • #12
                        Đúng là quan trọng nhất của bạn lúc này là xung đồng bộ CLK đấy, vì sơ đồ mà bạn vẽ lên đó chính là thuật toán rùi. Quan trọng là bây giờ bạn phải đòng bộ xung CLK, bạn nên nhớ, cứ có 1 xung CLK thì thanh ghi sẽ ghi lại, hoặc là dịch và ghi, hoặc là ghi luôn,tùy lập trình của bạn cho thanh ghi đó, vì đó là thanh ghi đồng bộ xung clk mà. Giản đồ sóng khi vẽ ra ít nhất phải kiểm chứng đc nó đúng trong những giá trị bạn test, sau đó còn phải test đủ Random các trường hợp nữa nhé.

                        Đây là kết quả mô phỏng trên Modelsim:
                        Click image for larger version

Name:	Capture.jpg
Views:	1
Size:	67.0 KB
ID:	1367692

                        bạn thấy là 32768: 128 = 256 dư 0.

                        chúc bạn thành công!

                        Comment


                        • #13
                          Nguyên văn bởi siskin_lion Xem bài viết
                          Đúng là quan trọng nhất của bạn lúc này là xung đồng bộ CLK đấy, vì sơ đồ mà bạn vẽ lên đó chính là thuật toán rùi. Quan trọng là bây giờ bạn phải đòng bộ xung CLK, bạn nên nhớ, cứ có 1 xung CLK thì thanh ghi sẽ ghi lại, hoặc là dịch và ghi, hoặc là ghi luôn,tùy lập trình của bạn cho thanh ghi đó, vì đó là thanh ghi đồng bộ xung clk mà. Giản đồ sóng khi vẽ ra ít nhất phải kiểm chứng đc nó đúng trong những giá trị bạn test, sau đó còn phải test đủ Random các trường hợp nữa nhé.

                          Đây là kết quả mô phỏng trên Modelsim:
                          [ATTACH=CONFIG]52874[/ATTACH]

                          bạn thấy là 32768: 128 = 256 dư 0.

                          chúc bạn thành công!
                          bạn ơi, mình cũng làm 1 đồ án tương tự, nhưng là chia 2k bit cho 2k bit chứ ko phải là 2k bit cho k bit (vấn đề này mình làm được rồi)
                          hai nữa là bạn ý cũng như mình đều làm bộ chia cụ thể, như bạn ý là 8bit:4bit còn mình làm 8bit:8bit nhưng yêu cầu đặt ra là 2k bit chia cho k bit chung chung chứ ko phải cụ thể ntn
                          thứ 3 là yêu cầu cần thêm là phép chia này phải được xử lý ra kết quả là số thập phân, có cả phần nguyên và phần thập phân (xử lý từ số dư) sao cho dấu phẩy tĩnh nằm chính giữa

                          help me! :/

                          Comment


                          • #14
                            Nguyên văn bởi tonyvandinh Xem bài viết
                            Tất cả mọi khối trên hình trên phải hoạt động trong cùng một xung clock. Cần 5 xung clock để làm xong tính chia ở trên. Bạn có thể dùng bộ đếm để xác định khi nào nhận đường vào mới và khi nào thì cộng việc chia đã hoàn tất.

                            Code ở trên không có đủ chi tiết nên tôi không biết lỗi ở đâu nhưng hy vọng bạn có thể tìm ra. Chúc may mắn

                            Nguyên văn bởi siskin_lion Xem bài viết
                            Đúng là quan trọng nhất của bạn lúc này là xung đồng bộ CLK đấy, vì sơ đồ mà bạn vẽ lên đó chính là thuật toán rùi. Quan trọng là bây giờ bạn phải đòng bộ xung CLK, bạn nên nhớ, cứ có 1 xung CLK thì thanh ghi sẽ ghi lại, hoặc là dịch và ghi, hoặc là ghi luôn,tùy lập trình của bạn cho thanh ghi đó, vì đó là thanh ghi đồng bộ xung clk mà. Giản đồ sóng khi vẽ ra ít nhất phải kiểm chứng đc nó đúng trong những giá trị bạn test, sau đó còn phải test đủ Random các trường hợp nữa nhé.

                            Đây là kết quả mô phỏng trên Modelsim:
                            [ATTACH=CONFIG]52874[/ATTACH]

                            bạn thấy là 32768: 128 = 256 dư 0.

                            chúc bạn thành công!
                            bạn ơi, mình cũng làm 1 đồ án tương tự, nhưng là chia 2k bit cho 2k bit chứ ko phải là 2k bit cho k bit (vấn đề này mình làm được rồi)
                            hai nữa là bạn ý cũng như mình đều làm bộ chia cụ thể, như bạn ý là 8bit:4bit còn mình làm 8bit:8bit nhưng yêu cầu đặt ra là 2k bit chia cho k bit chung chung chứ ko phải cụ thể ntn
                            thứ 3 là yêu cầu cần thêm là phép chia này phải được xử lý ra kết quả là số thập phân, có cả phần nguyên và phần thập phân (xử lý từ số dư) sao cho dấu phẩy tĩnh nằm chính giữa

                            help me! :/

                            Comment

                            Về tác giả

                            Collapse

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

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

                            Collapse

                            Đang tải...
                            X