Thông báo

Collapse
No announcement yet.

Sự khác nhau giữa biến và tín hiệu trong lập trình VHDL !

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

  • #76
    Nguyên văn bởi yesme@ Xem bài viết
    Đúng là thông thường chúng ta dùng các constraints để đạt được một P&R tối ưu nhất (tối ưu theo nghĩa chúng ta cần). Tuy nhiên, trong một số trường hợp chúng ta có thể dùng các constraints này đề ép tool đưa ra một số thông số phần cứng mà chúng ta mong muốn. Ví dụ, nếu có hai đường tín hiệu A và B, bạn có thể xây dựng các ràng buộc sao cho trễ ở A luôn luôn lớn hơn trễ ở B.
    Tôi chỉ dùng Xilinx nên không rõ về các hardware khác.

    Với Xilinx, bạn có thể yêu cầu:
    net "A" offset = in 5ns before clk;
    net "B" offset = in 10ns before clk;

    Nhưng nếu offset A = 12 và B = 11, B trễ hơn A, nhưng hoàn toàn đạt yêu cầu. Làm cách nào mà bạn có thể ép cho A luôn luôn trễ hơn B?

    Trên thực tế, tôi chưa gặp qua trường hợp mà A bắt buộc phải trễ hơn B (nếu có thể làm được), vì offset chỉ có hiệu lực trước khi A và B được clock vào flip-flop, sau đó thì tất cả đều synchronous với clock.

    Còn constraint nào có thể dùng được?

    Comment


    • #77
      Chào mấy bác, tui đang làm một khối điếm có chức năng như sau (hình):
      Bô đếm thay vì đếm dựa vào xung clk, thì sẽ đếm dựa vào giá trị của một bộ đếm khác. Vì yêu cầu thiết kế nên bộ đếm đó phải hoạt động như sau:
      Khi bộ counter_1 đếm tới 6 thì nó sẽ bị xóa về 0. Đồng thời khi counter_1 có giá trị là 6 thì bộ counter_2 đếm lên 1.
      Tui viết code như sau:

      library IEEE;
      use IEEE.STD_LOGIC_1164.ALL;
      use IEEE.STD_LOGIC_ARITH.ALL;
      use IEEE.STD_LOGIC_UNSIGNED.ALL;
      ---------------------------------------------------------------------
      entity counter_global is
      Port ( reset : in STD_LOGIC;--input reset counter_global
      clk : in STD_LOGIC;--clock of counter_global
      count_out : out STD_LOGIC_VECTOR (2 downto 0);--control read RAM
      pulse_out : out STD_LOGIC_VECTOR (2 downto 0));--control pulse_count unit
      end counter_global;
      ---------------------------------------------------------------------
      architecture Behavioral of counter_global is

      begin
      -------------------------------
      counter_global: process(reset,clk)
      variable count_global : integer range 0 to 6 :=0;
      variable count_temp : integer range 0 to 6 ;
      begin

      if reset = '1' then
      count_global := 0;
      elsif clk='1' and clk'event then
      count_global := count_global + 1;
      end if;
      if count_global = 6 then
      count_global :=0 ;
      end if ;

      if count_global = 6 then
      count_temp := count_temp + 1 ;
      end if ;
      count_out <= conv_std_logic_vector(count_global,3) ;
      pulse_out <= conv_std_logic_vector(count_temp,3) ;
      end process ;

      end Behavioral;


      (xem ảnh )

      Kết quả là counter_2 không hề đếm (cả mô phỏng lẫn thực tế).
      Sau đó tui sửa lại :
      từ :
      if count_global = 6 then
      count_temp := count_temp + 1 ;

      thành :
      if count_global = 5 then
      count_temp := count_temp + 1 ;


      Kết quả là trong mô phỏng counter_2 đếm như ý đồ, nhưng thực tế khi đo xung thấy nhiễu quá nhiều, chứ nó không mịn như giá trị đếm của counter_1.

      Mấy bác có giải pháp nào không ?
      Attached Files

      Comment


      • #78
        Nguyên văn bởi thavali Xem bài viết
        Chào mấy bác, tui đang làm một khối điếm có chức năng như sau (hình):
        Bô đếm thay vì đếm dựa vào xung clk, thì sẽ đếm dựa vào giá trị của một bộ đếm khác. Vì yêu cầu thiết kế nên bộ đếm đó phải hoạt động như sau:
        Khi bộ counter_1 đếm tới 6 thì nó sẽ bị xóa về 0. Đồng thời khi counter_1 có giá trị là 6 thì bộ counter_2 đếm lên 1.
        Tui viết code như sau:

        library IEEE;
        use IEEE.STD_LOGIC_1164.ALL;
        use IEEE.STD_LOGIC_ARITH.ALL;
        use IEEE.STD_LOGIC_UNSIGNED.ALL;
        ---------------------------------------------------------------------
        entity counter_global is
        Port ( reset : in STD_LOGIC;--input reset counter_global
        clk : in STD_LOGIC;--clock of counter_global
        count_out : out STD_LOGIC_VECTOR (2 downto 0);--control read RAM
        pulse_out : out STD_LOGIC_VECTOR (2 downto 0));--control pulse_count unit
        end counter_global;
        ---------------------------------------------------------------------
        architecture Behavioral of counter_global is

        begin
        -------------------------------
        counter_global: process(reset,clk)
        variable count_global : integer range 0 to 6 :=0;
        variable count_temp : integer range 0 to 6 ;
        begin

        if reset = '1' then
        count_global := 0;
        elsif clk='1' and clk'event then
        count_global := count_global + 1;
        end if;
        if count_global = 6 then
        count_global :=0 ;
        end if ;

        if count_global = 6 then
        count_temp := count_temp + 1 ;
        end if ;
        count_out <= conv_std_logic_vector(count_global,3) ;
        pulse_out <= conv_std_logic_vector(count_temp,3) ;
        end process ;

        end Behavioral;


        (xem ảnh )

        Kết quả là counter_2 không hề đếm (cả mô phỏng lẫn thực tế).
        Sau đó tui sửa lại :
        từ :
        if count_global = 6 then
        count_temp := count_temp + 1 ;

        thành :
        if count_global = 5 then
        count_temp := count_temp + 1 ;


        Kết quả là trong mô phỏng counter_2 đếm như ý đồ, nhưng thực tế khi đo xung thấy nhiễu quá nhiều, chứ nó không mịn như giá trị đếm của counter_1.

        Mấy bác có giải pháp nào không ?
        Vấn đề do count_global là variable. Vì đoạn code
        if count_global = 6 then
        count_global :=0 ;
        nằm ở trên reset count_global := 0, cho nên đoạn code ở dưới không bao giờ thấy được count_global = 6.
        if count_global = 6 then
        count_temp := count_temp + 1 ;

        Mình khuyên bạn nên viết cho đúng chuẩn hơn và để tất cả các operations vào trong phần if rising_edge(clk) .... end if, nếu không, khi simulate, các variable có thể đổi cho cả hai clock edge, và khi synthesize có thể sẽ không như ý của bạn, và rất dễ bị glitch khi chạy trên hardware.

        Comment


        • #79
          Cảm ơn bác. Như bác đã thấy ở hình trên, Bộ counter_2 chỉ đếm dựa vào giá trị count_global = 6, chứ không dựa vào event'clk, nên tui không đưa bộ đếm counter_2 vào trong event'clk. Bác có thể sửa lại đoạn code tôi viết ở trên cho đúng với ý muốn được không nhỉ ?

          Comment


          • #80
            Nguyên văn bởi thavali Xem bài viết
            Cảm ơn bác. Như bác đã thấy ở hình trên, Bộ counter_2 chỉ đếm dựa vào giá trị count_global = 6, chứ không dựa vào event'clk, nên tui không đưa bộ đếm counter_2 vào trong event'clk. Bác có thể sửa lại đoạn code tôi viết ở trên cho đúng với ý muốn được không nhỉ ?
            Bạn nói chưa hoàn toàn đúng. Đúng là giá trị của count_temp thay đổi khi count_global = 6, nhưng giá trị của count_temp được giữ ở đâu? Cũng được giữ trong flip-flop thôi, mà flip-flop hoàn toàn phụ thuộc vào clock edge, cho nên vẫn không thể để count_temp ở ngoài clk'event được. Trong trường hợp này, (count_global = 6) là một clock enable cho flip-flop của count_temp.

            Logic error trong code của bạn là:
            if count_global = 6 then
            count_global :=0 ;
            nên được để sau
            if count_global = 6 then
            count_temp := count_temp + 1 ;

            Syntax error, như đã nói ở trên, các giá trị được lưu giữ (count_global và count_temp) phải được để bên trong clk'event.

            Lúc trước tôi làm TA cho cái lớp vỡ lòng, ra đi làm cũng được một thời gian rồi, cho nên tin tôi đi, syntax của bạn không dùng được. Simulate thì có thể miễn cưỡng được, và synthesize thì có thể gặp may mắn với những bài nhỏ nhỏ thôi.

            Comment


            • #81
              Trao đổi với mấy bác tui thấy rất bổ ích.
              Vâng. Tui hiểu ý bác. Nhưng, như hình trên, khối counter_1counter_2 là riêng biệt, và được nối với nhau nhờ bus tín hiệu (đường ở giữa 2 khối , hình trên ), và tôi viết 2 khối này riêng nhau, sau đó port map chúng, do đó trong khi viết khối counter_2 , trong khai báo entity không có tín hiệu clk ở ngõ vào, do đó khối counter_2 chỉ bị ảnh hưởng bởi bus kết nối ( bus này chính là giá trị của counter_1, trong đoạn chương trình trên chính là count_global ).
              Trong project của tui, tui phải dùng nhiều khối, nên tui viết các khối rồi port map lại, do vậy có những khối mà trong danh sách nhạy (sensitive list ) không có clk, tức không cần rising hay falling. Bây giờ tui đang test mạch nên cũng chưa biết kết quả như thế nào. Sau khi có kết quả sẽ trao đổi tiếp với mấy bác.

              Comment


              • #82
                Chào mấy bác, hiện thời tui đang cần viết một khối chức năng sau:
                Khối này sẽ nhận dữ liệu từ một MCU (LPC2212), truyền theo giao thức SPI .
                Khối này có ngõ vào và ra như hình. Cách hoạt động:
                MCU luôn là master còn khối CPLD là slave, khối CPLD có chức năng là chứa data nhận được từ MCU ,rồi đưa tới ngõ ra khi được cho phép (chân OE), nếu OE không cho phép thì data nhận được vẫn ở trong khối CPLD còn ngõ ra out(7:0) là High_Z. Khi nhận đủ data từ MCU (8bit) thì cờ flag set lên 1. Hình dưới là giao thức SPI của MCU LPC 2212.

                các bác có cái source code nào cho cái khối này không cho tui xin phát , hay có thể hướng dẫn giúp tui cái khung chương trình như thế nào không, chẳn hạn, qui trình truyền data được thực hiện theo thứ tự như thế nào ?

                2. Bác nào có tài liệu về các tập lệnh trong VHDL không, cho tui xin luôn nhé ?
                Attached Files
                Last edited by thavali; 14-07-2007, 14:40.

                Comment


                • #83
                  Trong cuốn sách "Circuit Design With VHDL - Volnei A. Pedroni -© MIT 2004". Tác giả có nói: "...Such packages (std_logic_signed , std_logic_unsigned) allow operations with STD_LOGIC_VECTOR data to be performed as if the data were of type SIGNED or UNSIGNED, respectively..." (trang 48-50).
                  Như thế có nghĩa là nếu mình khai báo thư viện : USE eee.std_logic_unsigned.all; thì giá trị của STD_LOGIC_VECTOR được hiểu như số không dấu, ngược lại nếu khai báo thư viện là :USE eee.std_logic_signed.all; thì giá trị của STD_LOGIC_VECTOR là số có dấu.
                  Tui đã viết 1 đoạn code để test thử nhưng không nhận thấy sự khác biệt nào khi sử dụng hai thư viện này, Mấy bác có thể giải thích về ảnh hưởng của hai thư viện này lên STD_LOGIC_VECTOR không ? Xin cho kèm ví dụ.

                  Comment


                  • #84
                    std_logic_signed/unsigned là thư viện mở rộng của std_logic_arith dùng để xử lý các thao tác toán học với các toán hạng có kiểu std_logic_vector.

                    std_logic_signed tương đương với biến nguyên có dấu và std_logic_unsigned tương đương với biến nguyên không dấu.

                    Các thao tác toán học được định nghĩa giống như trong std_logic_arith ngoại trừ chúng xem các toán hạng std_logic_signed/std_logic_unsigned như là các argument và xử lý các toán hạng này dưới dạng các số nguyên có dấu bù 2/dưới dạng các số nguyên không dấu.

                    Để dễ hiểu hơn bạn nên mở thư viện std_logic_signed/unsigned ra và so sánh với std_logic_arithm. Bạn chỉ cần xem một hoặc hai functions là có thể hiểu ngay.


                    Comment


                    • #85
                      Good boy,
                      Tớ thấy bạn hỏi rất chi li về các khía cạnh của VHDL, đó là bước ban đầu của những người mới học.Rất tốt đấy chứ. FPGA không có mới mẻ gì cả, đơn giản vì sinh viên chúng ta không có nhiều cơ hội tiếp cận nó khi còn học trong trường đại học, thiếu KIT, thiếu người hướng dẫn ... Giống như người chưa học thì thấy vi điều khiển là thứ kinh khủng gì đó, nghịch thời gian thấy chán, rồi lại thấy FPGA là cái trên trời gì đó, mượn KIT về nghịch xong cũng thấy chán vì ko thấy nó có gì đặc biệt. Tớ ko biết người ta thiết kế các ứng dụng trên FPGA rồi bán ra như thế nảo cả? Nhưng khi thiết kế IC nó chỉ có mỗi một chức năng là test thử một số module sau khi coding RTL, và tầm quan trọng cũng hạn chế.

                      Tớ có chút thông tin chia sẻ, khi bạn tham gia vào các project lớn, cần nhiều kĩ sư tham gia làm việc teamwork, bạn sẽ thấy quy tắc đặt tên, và phong cách viết code là tối quan trọng, và có những có những cú pháp không những không nên mà còn bị cấm sử dụng như một số cú pháp bạn thử ở trên. Vì vậy khi mới học ngoài việc học cách hiểu code, viết code bạn nên chú ý về cách đặt tên biến, tín hiệu, các cấu trúc mình sử dụng (không phải tôi thích dùng cấu trúc nào tôi thích cũng được, tất nhiên khi mới học thì nên thử nhiều như có thể để lấy kinh nghiệm) ...Và có một câu mình nghĩ nên nhớ khi mới học đó là :

                      "Đơn giản là tốt nhất, bạn giỏi hơn người và viết ra những code tuỵêt vời nhưng partner của bạn đọc ko hiểu thì code bạn là vô dụng"

                      Best regards.

                      Comment


                      • #86
                        Nguyên văn bởi thavali Xem bài viết
                        Trong cuốn sách "Circuit Design With VHDL - Volnei A. Pedroni -© MIT 2004". Tác giả có nói: "...Such packages (std_logic_signed , std_logic_unsigned) allow operations with STD_LOGIC_VECTOR data to be performed as if the data were of type SIGNED or UNSIGNED, respectively..." (trang 48-50).
                        Như thế có nghĩa là nếu mình khai báo thư viện : USE eee.std_logic_unsigned.all; thì giá trị của STD_LOGIC_VECTOR được hiểu như số không dấu, ngược lại nếu khai báo thư viện là :USE eee.std_logic_signed.all; thì giá trị của STD_LOGIC_VECTOR là số có dấu.
                        Tui đã viết 1 đoạn code để test thử nhưng không nhận thấy sự khác biệt nào khi sử dụng hai thư viện này, Mấy bác có thể giải thích về ảnh hưởng của hai thư viện này lên STD_LOGIC_VECTOR không ? Xin cho kèm ví dụ.

                        Bạn không nên dùng std_logic_unsigned và std_logic_signed. Hai thư viện trên là của Synopsis. Bạn nên dùng ieee.numeric_std.all, là thư viện theo chuẩn IEEE, cũng có unsigned/signed.

                        Thay vì declare:
                        signal my_signal: std_logic_vector(31 downto 0);
                        bạn có thể declare:
                        signal my_signal: unsigned(31 downto 0); hoặc
                        signal my_signal: signed(31 downto 0);

                        Với std_logic_vector bạn không thể dùng lẫn lộn giữa vector và integer: my_signal <= my_signal + 5, nhưng nếu my_signal là unsigned/signed thì hoàn toàn ok. Khi compare cũng vậy. Nói chung thì unsigned/signed tiện dụng hơn khi phải làm các math operations.

                        Comment


                        • #87
                          Nguyên văn bởi TheKing Xem bài viết
                          Good boy,
                          Tớ thấy bạn hỏi rất chi li về các khía cạnh của VHDL, đó là bước ban đầu của những người mới học.Rất tốt đấy chứ. FPGA không có mới mẻ gì cả, đơn giản vì sinh viên chúng ta không có nhiều cơ hội tiếp cận nó khi còn học trong trường đại học, thiếu KIT, thiếu người hướng dẫn ... Giống như người chưa học thì thấy vi điều khiển là thứ kinh khủng gì đó, nghịch thời gian thấy chán, rồi lại thấy FPGA là cái trên trời gì đó, mượn KIT về nghịch xong cũng thấy chán vì ko thấy nó có gì đặc biệt. Tớ ko biết người ta thiết kế các ứng dụng trên FPGA rồi bán ra như thế nảo cả? Nhưng khi thiết kế IC nó chỉ có mỗi một chức năng là test thử một số module sau khi coding RTL, và tầm quan trọng cũng hạn chế.
                          FPGA thường được dùng cho các SDR (software-defined radio) cho các communication applications.

                          Thường thì data lấy từ các A/D (analog to digital converter). Trong FPGA thì có thể đi qua DDC -> polyphase filter -> FFT hoặc DDC -> FIR filter, vv. Sau đó thì có thể làm các thuật toán như Q-R/Cholesky decomposition, hoặc tìm eigenvector, eigenvalue, correlation coefficient để định hướng của signal, demodulate để nghe audio, vv. Phần toán không khó, nhưng design phải năng động (dùng generic, generate, inferred memory, vv.). Array cần đổi từ 4x4x2 lên 16x16x1, đổi generic và re-synthesize... cần dùng 8 FIR filters thay vì 5, đổi generic và re-synthesize ... thay vì phải re-design.

                          Ngoài các thuật toán ra, cũng có thể cần design các module khác như PCI/X controller, DMA controller, các memory controllers (SRAM, SDRAM, DDR, DDR2, QDR, vv).

                          Nói chung thì học viết VHDL không khó, nhưng viết để làm vào việc gì? Viết xong rồi, có thể viết để synthesize nhanh hơn và nhỏ hơn không? Phải không ngừng học hỏi.

                          Ngoài phần implementation, cũng đừng quên khâu design và test (kit không quan trọng, quan trọng là khả năng viết testbench).
                          Last edited by nemesis21; 22-07-2007, 00:28.

                          Comment


                          • #88
                            sách của Volnei A. Pedroni viết về phần này hơi dài nên trích dẫn hơi bất tiện nhưng tui cũng muốn đưa lên luôn cho dễ thảo luận:
                            Code:
                            VHDL contains a series of pre-defined data types, specified through the IEEE 1076
                            and IEEE 1164 standards. More specifically, such data type definitions can be found in the following packages / libraries:
                            1. Package standard of library std: Defines BIT, BOOLEAN, INTEGER, and REAL
                            data types.
                            2. Package std_logic_1164 of library ieee: Defines STD_LOGIC and STD_ULOGIC
                            data types.
                            3. Package std_logic_arith of library ieee: Defines SIGNED and UNSIGNED
                            data types, plus several data conversion functions, like conv_integer(p),
                            conv_unsigned(p, b), conv_signed(p, b), and conv_std_logic_vector(p, b).
                            4. Packages std_logic_signed and std_logic_unsigned of library ieee: Contain functions
                            that allow operations with STD_LOGIC_VECTOR data to be performed as if the
                            data were of type SIGNED or UNSIGNED, respectively.
                            Như vậy std_logic_unsigned và std_logic_signed là thư viện mở rộng của std_logic_arith chứ bác nemesis21 ?

                            Code:
                            As mentioned earlier, these types are defined in the std_logic_arith package of the
                            ieee library. Their syntax is illustrated in the examples below.
                            Examples:
                            SIGNAL x: SIGNED (7 DOWNTO 0);
                            SIGNAL y: UNSIGNED (0 TO 3);
                            Notice that their syntax is similar to that of STD_LOGIC_VECTOR, not like that
                            of an INTEGER, as one might have expected.
                            An UNSIGNED value is a number never lower than zero. For example, ‘‘0101’’
                            represents the decimal 5, while ‘‘1101’’ signifies 13. If type SIGNED is used instead,
                            the value can be positive or negative (in two’s complement format). Therefore,
                            ‘‘0101’’ would represent the decimal 5, while ‘‘1101’’ would mean -3.
                            To use SIGNED or UNSIGNED data types, the std_logic_arith package, of
                            the ieee library, must be declared. Despite their syntax, SIGNED and UNSIGNED 
                            data types are intended mainly for arithmetic operations, that is, contrary to
                             STD_LOGIC_VECTOR, they accept arithmetic operations. On the other hand,
                             logical operations are not allowed. With respect to relational (comparison)
                             operations, there are no restrictions.
                            Như vậy để khai báo :
                            SIGNAL x: SIGNED (7 DOWNTO 0);
                            SIGNAL y: UNSIGNED (0 TO 3);
                            thì ta chỉ cần std_logic_arith thôi chứ không cần tới ieee.numeric_std.all ?

                            vd: (trích của tác giả)

                            Code:
                            LIBRARY ieee;
                            USE ieee.std_logic_1164.all;
                            USE ieee.std_logic_arith.all; -- extra package necessary
                            ...
                            SIGNAL a: IN SIGNED (7 DOWNTO 0);
                            SIGNAL b: IN SIGNED (7 DOWNTO 0);
                            SIGNAL x: OUT SIGNED (7 DOWNTO 0);
                            ...
                            v <= a + b; -- legal (arithmetic operation OK)
                            w <= a AND b; -- illegal (logical operation not OK)
                            Ngược lại nếu không dùng có std_logic_arith thì :

                            Code:
                            LIBRARY ieee;
                            USE ieee.std_logic_1164.all; -- no extra package required
                            ...
                            SIGNAL a: IN STD_LOGIC_VECTOR (7 DOWNTO 0);
                            SIGNAL b: IN STD_LOGIC_VECTOR (7 DOWNTO 0);
                            SIGNAL x: OUT STD_LOGIC_VECTOR (7 DOWNTO 0);
                            ...
                            v <= a + b; -- illegal (arithmetic operation not OK)
                            w <= a AND b; -- legal (logical operation OK)
                            do đó tác giả nói:
                            Code:
                            Despite the constraint mentioned above, there is a simple way of allowing data of 
                            type STD_LOGIC_VECTOR to participate directly in arithmetic operations. For that, the ieee
                             library provides two packages, std_logic_signed and std_logic_unsigned, which allow 
                            operations with STD_LOGIC_VECTOR data to be performed as if the data were of type 
                            SIGNED or UNSIGNED, respectively.
                            Ví dụ dưới đây tác giả xài std_logic_unsigned, không dùng std_logic_arith :

                            Vd: ( các vd điều là của tác giả)

                            Code:
                            LIBRARY ieee;
                            USE ieee.std_logic_1164.all;
                            USE ieee.std_logic_unsigned.all; -- extra package included
                            SIGNAL a: IN STD_LOGIC_VECTOR (7 DOWNTO 0);
                            SIGNAL b: IN STD_LOGIC_VECTOR (7 DOWNTO 0);
                            SIGNAL x: OUT STD_LOGIC_VECTOR (7 DOWNTO 0);
                            ...
                            v <= a + b; -- legal (arithmetic operation OK), unsigned
                            w <= a AND b; -- legal (logical operation OK)
                            ví dụ này cho thấy : std_logic_unsigned và std_logic_signed chỉ ảnh hưởng tới STD_LOGIC_VECTOR (ảnh hưởng về dấu). Nếu ta không quan tâm tới dấu của STD_LOGIC_VECTOR, hay thực hiện các phép toán số học (Arithmetic) trên STD_LOGIC_VECTOR thì ta không cần tới hai thư viện này (std_logic_unsigned và std_logic_signed).
                            --------------------------------------
                            Như vậy, để xài : (theo bác nemesis21)

                            signal my_signal: unsigned(31 downto 0); hoặc
                            signal my_signal: signed(31 downto 0);

                            ta chỉ cần khai báo: std_logic_arith là đủ (đương nhiên phải có std_logic_1164 ) chứ không cần numeric_std.
                            Ngược lại: std_logic_unsigned và std_logic_signed chỉ sử dụng cho STD_LOGIC_VECTOR. Bình thường chỉ cần std_logic_1164 là xài được STD_LOGIC_VECTOR, nhưng để có thể thao tác trực tiếp các phép toán số học (arithmetic) trên STD_LOGIC_VECTOR thì phải thêm std_logic_unsigned hoặc std_logic_signed. Và tui muốn hỏi ở chỗ này, (chính xác là cần 1 vd minh họa) : Khi xài thêm std_logic_unsigned thì STD_LOGIC_VECTOR là unsigned tức viết 1101 thì khi chuyển sang số integer sẽ là 13. ngược lại, Khi xài thêm std_logic_signed thì STD_LOGIC_VECTOR là signed tức viết 1101 thì khi chuyển sang số integer sẽ là -3.

                            xin trích lại:
                            Code:
                            An UNSIGNED value is a number never lower than zero. For example, ‘‘0101’’
                            represents the decimal 5, while ‘‘1101’’ signifies 13. If type SIGNED is used instead,
                            the value can be positive or negative (in two’s complement format). Therefore,
                            ‘‘0101’’ would represent the decimal 5, while ‘‘1101’’ would mean -3.
                            Nhưng tui không tìm ra một trường hợp (ví dụ) nào để thể minh họa đều trên. Cả sách của tác giả cũng không có vd nào cả. Mong mấy bác tiếp tục hỗ trợ

                            @ TheKing: Tui thấy cái FPGA cũng có thể xài trong khá nhiều việc đấy chứ bác, chỉ việc test ASIC thôi cũng quan trọng rồi. Nói chung tui chỉ là tân binh về FPGA nên cũng không hiểu nhiều về tình hình ứng dụng của nó. Thôi kệ, cứ học đi đã, tui vừa có cái kit SPATAN-3E của xilinx nên cứ thế mà chiến .
                            Last edited by thavali; 23-07-2007, 11:03.

                            Comment


                            • #89
                              Mình thấy các phần giải thích trong cuốn sách mà bạn đã copy và post lên bài viết trên khá rõ ràng. Mình không hiểu bạn muốn có thêm ví dụ gì nữa.

                              Bạn thử gõ một đoạn lệnh sử dụng kiểu signed vector và chạy chương trình mô phỏng thì sẽ thấy kết quả của nó. Ví dụ:

                              Library iee;
                              Use ieee.std_logic_1164.all;
                              Use ieee.std_logic_signed.all;

                              Signal a : IN std_logic_vector (3 downto 0);
                              Signal b : IN std_logic_vector (3 downto 0);
                              Signal c : OUT std_logic_vector (3 downto 0);

                              a <= "0011"; -- a nhận giá trị 3
                              b <= "1101"; -- b nhận giá trị -3 (được quy đổi từ 101 -> 010 -> 010 + 1 -> 011 và nhận dấu (-)
                              c <= a + b; -- toán tử + ở đây được định nghĩa trong std_logic_signed (phép cộng giữa hai véc tơ có dấu), bạn có thể mở gói std_logic_signed ra xem.

                              Kết quả mô phỏng sẽ cho c = "0000".


                              Comment


                              • #90
                                Cảm ơn bác yesme. Tui cũng đã nhiều lần test những ví dụ tương tự như trên, bây giờ là cả ví dụ của bác. Tui rút ra được kết luận sau:
                                Về mặt phần cứng ta không thể thu được kết quả như tui mong đợi : chẳn hạn, lấy ví dụ trên của bác. Khi tổng hợp ta thu được tín hiệu c = "0000". Nhưng sau đó ta đổi thư viện thành Use ieee.std_logic_unsigned.all; thì kết quả c vẫn là "0000" vì giá trị 13 + 3 = 16 ="10000" nên c bị tràn.
                                Để không bị tràn tui lấy 1 số nhỏ hơn: (xem hình)
                                Trong đoạn chương trình dưới (hình) ta thấy:

                                Code:
                                a <= "0001" ; --số dương 1.
                                b <= "1000" ; --số -8 vì dùng STD_LOGIC_SIGNED.  
                                c <= a + b ;  --số -7
                                Giá trị nhị phân của - 7 là "1001" như vậy giá trị của c lúc này là "1001" .
                                Bây giờ ta đổi thư viện thành: use IEEE.STD_LOGIC_UNSIGNED.ALL;. Như thế :
                                Code:
                                a <= "0001" ; --số dương 1.
                                b <= "1000" ; --số 8 vì dùng STD_LOGIC_UNSIGNED.  
                                c <= a + b ;  --số 9
                                Giá trị nhị phân của 9 là "1001" như vậy giá trị của c cũng là "1001" .
                                Như vậy cho dù dùng signed hay unsiged thì c vẫn là "1001". (mạch tổng hợp đúng như vậy). Rõ ràng ta không thấy sự khác biệt khi dùng std_logic_unsigned hay std_logic_signed .
                                Do đó, để nhận thấy sự khác nhau của std_logic_unsigned và std_logic_signed thì ta phải thực hiện thêm bước nữa:
                                1. Đổi c thành số integer, tuy vậy cách này không xài được vì các hàm chuyển sang integer như conv_integer(p,b), to_integer điều không hỗ trợ tham số vào là std_logic_vector.
                                2. cách khác là dùng lại ví dụ của bác ở trên và phải dùng cách nào đó để lấy được giá trị bit tràn và tùy theo cách khai báo là signed hay unsigned mà bit tràn là 0 hay 1 :

                                dùng std_logic_signed:
                                a <= "0011"; -- a nhận giá trị 3
                                b <= "1101"; -- b nhận giá trị -3
                                c <= a + b ; -- bằng 0, không có tràn

                                ------------------------
                                dùng std_logic_unsigned:
                                a <= "0011"; -- a nhận giá trị 3
                                b <= "1101"; -- b nhận giá trị 13
                                c <= a + b ; -- bằng 16, có tràn => cần lấy bit tràn này.

                                Bây giờ tui chưa nghĩ ra được ví dụ nào như thế , nhưng nếu làm được như vậy thì mới nhận thấy sự khác biệt của std_logic_unsigned và std_logic_signed , từ đó mới suy ra mạch tổng hợp sẽ có hành vi khác nhau đối với std_logic_unsigned và std_logic_signed, còn nếu chỉ dùng ví dụ như của bác hay của tui viết ở trên (hình) thì không nhận thấy sự khác biệt này.

                                có thể những quan điểm trên đây của tui là chưa đúng, mong mấy bác cùng góp ý, bổ sung
                                Attached Files

                                Comment

                                Về tác giả

                                Collapse

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

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

                                Collapse

                                Đang tải...
                                X