Thông báo

Collapse
No announcement yet.

Tạo task trong Quantus II

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

  • Tạo task trong Quantus II

    Hi Alls!
    Tôi đang làm 1 project thiết kế IP core interrupt controller viết bằng Verilog, tôi đã simulation thiết kế trên Questasim và cho kết quả chính xác.
    Trong quá trình simulation, tôi đã tạo task Write để ghi giá trị vào cho thanh ghi, module của tôi như sau :
    Code:
    task WRITE;
         input [15:0] addr_task;
         input [7:0]  data;
         //---start---------------
         begin
            paddr   <= 16'hz;
            pwrite  <= 0;
            psel    <= 0;
            penable <= 0;
            pwdata  <= 8'hz; 
           //---clock thu nhat------
           @(posedge pclk);
           #0.5
           begin
             paddr   <= addr_task;
             pwrite  <= 1;
             psel    <= 1;
             penable <= 0;
             pwdata  <= data; 
           end 
           //---clock thu 2------
           @(posedge pclk)
           #0.5
           begin
             paddr   <= addr_task;
             pwrite  <= 1;
             psel    <= 1;
             penable <= 1;
             pwdata  <= data; 
           end 
           //---clock thu ba----------
           @(posedge pclk)
           #0.5
           begin
             paddr   <= 16'hz;
             pwrite  <= 1;
             psel    <= 0;
             penable <= 0;
             pwdata  <= 8'hz; 
           end 
         end
      endtask
    Cách viết task này tôi tham khảo trên trang này Task And Function
    Bây giờ tôi dùng kit DE2 để chạy mô phỏng thiết kế này, cho 1 ứng dụng nhỏ là đếm lên và gặp giá trị nào đó thì cho xảy ra ngắt, dùng Led đơn và Led 7 đoạn để hiển thị interrupt.
    Vấn đề tôi gặp phải ở đây là Quantus II không hổ trợ simulation giống như tôi đã code ở trên, vậy thì muốn tạo 1 task có chức năng ghi dữ liệu vào thanh ghi thì phải làm thế nào trên Quantus II.
    Ai biết thì hướng dẫn tận tình dùm tôi với, tôi thành thật cảm ơn rất nhiều, mọi người cùng nhau trao đổi trên topic này để học hỏi thêm nha!

  • #2
    Code của bạn không chạy trên chip được bạn ạh, not synthesizable. Chỉ chạy mô phỏng được thôi. Bạn tìm hiểu thêm về synthesizable code.
    Đại khái là trên chip chỉ có : LUT và FF, tất cả những gì bạn mô tả sẽ được chuyển sang mạng lưới LUT với FF cho nên những statement như : #0.5 ... không thực hiện được trên chip.
    Bạn cần tìm hiểu cách mô tả thanh ghi, mô tả bộ đếm. Có thể tham khảo các template ở : Verilog

    Comment


    • #3
      Cám ơn anh đã quan tâm bài viết của em, em biết là Quantus không synthesizable code này rồi, em chỉ muốn hỏi là có cách nào khác để mình ghi giá trị vào thanh ghi hay không, em muốn làm công việc của thằng CPU, set address và đưa data và thanh ghi có có địa chỉ đã set, để mình hiện thực thiết kế thôi mà, em chỉ biết dùng task như trên đã đề cập. vì vậy em đăng topic để nhờ mọi người giúp đỡ.
      Thanks!

      Comment


      • #4
        Nguyên văn bởi thanhth90 Xem bài viết
        Cám ơn anh đã quan tâm bài viết của em, em biết là Quantus không synthesizable code này rồi, em chỉ muốn hỏi là có cách nào khác để mình ghi giá trị vào thanh ghi hay không, em muốn làm công việc của thằng CPU, set address và đưa data và thanh ghi có có địa chỉ đã set, để mình hiện thực thiết kế thôi mà, em chỉ biết dùng task như trên đã đề cập. vì vậy em đăng topic để nhờ mọi người giúp đỡ.
        Thanks!
        Mình chưa hiểu. Thanh ghi mà bạn nói là ở đâu ra?

        Comment


        • #5
          Nguyên văn bởi jefflieu Xem bài viết
          Mình chưa hiểu. Thanh ghi mà bạn nói là ở đâu ra?
          Thanh ghi này nằm trong thiết kế , những thanh ghi để set mode, priority, thanh ghi trang thái... của interrupt. Và mỗi thanh ghi được định danh bằng 1 địa chỉ cụ thể. Khi cần cấu hình thanh ghi thì chỉ cần set address và truyền data.
          Thân!

          Comment


          • #6
            Nguyên văn bởi thanhth90 Xem bài viết
            Thanh ghi này nằm trong thiết kế , những thanh ghi để set mode, priority, thanh ghi trang thái... của interrupt. Và mỗi thanh ghi được định danh bằng 1 địa chỉ cụ thể. Khi cần cấu hình thanh ghi thì chỉ cần set address và truyền data.
            Thân!
            Không biết có hiểu đúng ý bạn không, bạn đang muốn thiết kế 1 Bộ điểu khiển BUS, hoạt động ở chế độ master. Bus này sẽ xuất ra address và data dùng để ghi vào thanh ghi (ở một thiết kế khác) của bạn, đúng không?

            Comment


            • #7
              Đúng rồi đó anh, mục đích của em là nó đó, anh có thể cho em 1 giải pháp không!

              Comment


              • #8
                Nguyên văn bởi thanhth90 Xem bài viết
                Đúng rồi đó anh, mục đích của em là nó đó, anh có thể cho em 1 giải pháp không!
                Bạn viết 1 máy trạng thái (FSM) gồm 4 step nhu thế này:

                - IDLE:
                - READ:
                - WRITE:
                - DONE

                Từ IDLE, bạn chờ 1 nút nhấn gì đó (Nút R chẳng hạn), FSM của bạn sẽ nhảy qua READ, ở READ, bạn sẽ xuất ra các giá trị thích hợp của bus: address/data/read/write/chip select.
                Và khi thanh ghi đã được ghi rồi (giả sử bus của bạn có tín hiệu ack) thì FSM của bạn chạy qua done, chờ một thời gian rồi về IDLE ... cứ như thế cho write.
                ...
                Thay vì bạn làm cái task của bạn là chờ clock 1 clock 2 clock 3 gì đó thì bạn làm một FSM

                Đại khái là:
                case(state)
                IDLE : if(R) state <= READ; else if(W) state <= WRITE; else state <= IDLE;
                READ: begin
                if(ACK) state <= DONE;
                pread <= 1'b1;
                psel<=1'b1;
                pwrite <= 0;
                paddr <= ...
                end
                DONE : state <= IDLE;

                Bạn vẽ hình statemachine ra đi, với tín hiệu vào vào tín hiệu ra ...

                Comment


                • #9
                  Cám ơn anh đã giúp đỡ em, nhưng làm máy trạng thái em thấy không khả thi lắm.
                  Em ví dụ 1 đoạn ứng dụng thế này:
                  Code:
                  always ( posedge clk )
                  begin
                       if ( count == 5 )
                       begin
                            MOVT ( 16'h0003,8'h01 ) //set bit 0 cua thanh ghi IER len 1, cho phep ngat irq0
                            irq0 <= 1; // gọi ngắt 0
                            LEDR0 <= irq_rq; //khi co ngat la irq_rq = 1 va cho LEDR0 sang.
                            MOVT ( 16'h0004,8'h01 );// clear thanh ghi trang thai cua irq0
                       end
                       else
                            coun <= count +1;
                       end
                  end
                  Em cần set address và data bởi phần mềm chứ không dùng tới phần cứng, cũng giống như ngắt nội trong những con vi xử lý cơ bản, sau khi ngắt xong thì người lập trình clear nó, hoặc là set độ ưu tiên thì cũng dùng câu lệnh đã được định nghĩa.

                  Comment


                  • #10
                    Nguyên văn bởi thanhth90 Xem bài viết
                    Cám ơn anh đã giúp đỡ em, nhưng làm máy trạng thái em thấy không khả thi lắm.
                    Em ví dụ 1 đoạn ứng dụng thế này:
                    Code:
                    always ( posedge clk )
                    begin
                         if ( count == 5 )
                         begin
                              MOVT ( 16'h0003,8'h01 ) //set bit 0 cua thanh ghi IER len 1, cho phep ngat irq0
                              irq0 <= 1; // gọi ngắt 0
                              LEDR0 <= irq_rq; //khi co ngat la irq_rq = 1 va cho LEDR0 sang.
                              MOVT ( 16'h0004,8'h01 );// clear thanh ghi trang thai cua irq0
                         end
                         else
                              coun <= count +1;
                         end
                    end
                    Em cần set address và data bởi phần mềm chứ không dùng tới phần cứng, cũng giống như ngắt nội trong những con vi xử lý cơ bản, sau khi ngắt xong thì người lập trình clear nó, hoặc là set độ ưu tiên thì cũng dùng câu lệnh đã được định nghĩa.
                    Bạn đang không muốn dùng CPU mà, sao lại muốn set address và data bởi phần mềm? Phần mềm này ở đâu ra?
                    Mình nghĩ mình và bạn vẩn có gì đó hiểu lầm.

                    Theo mình hiểu hệ thống của bạn sẽ có :

                    - CPU (Tạm thời gọi nó vậy đi), CPU đơn giản chạy một ứng dụng đơn giản, set và thiết lập Bộ đếm
                    - Bộ đếm, sinh ra ngắt và ngắt CPU

                    2 phần này nốii với nhau qua bus và 1 tín hiệu ngắt ???

                    Bạn có bộ đếm rồi và muốn thiết kế phần CPU?

                    Bạn có thể làm một cai FSM khá phức tạp có khả năng đọc và giải mã microcode gồm có các state:
                    IDLE --> FETCH --> EXECUTE --> WRITE --> DONE, quay lại

                    ở state fetch bạn đọc ra một đoạn code từ trong ROM, rồi từ đó bạn thực hiện đoạn code đó.

                    Khi FSM của bạn bị ngắt, FSM phải load một địa chỉ định sẵn chỉ tới chỗ Interrupt Service Routine của bạn rồi thực hiện tiếp. Thực hiện xong thì quay lại chỗ mà nó đang thực hiện trước lúc bị ngắt....Khả thi/feasible?

                    Comment


                    • #11
                      Em xin nói cụ thể thiết kế của em thế này:
                      - Em thiết kế 1 IP cores Interrupt Controller, IP của em có input gồm nhiều tín hiệu ngắt (nội và ngoại), output là 1 tín hiệu ngắt và 1 vector_number để định danh interrupt đang được thực hiện
                      - Các interrupt này sẽ được set độ ưu tiên bởi các thanh ghi priority, độ ưu tiên có thể thay đổi, tùy vào người lập trình.
                      - Em muốn hiện thực thiết kế của mình bằng cách đỗ code Verilog lên FPGA, dùng 1 led đơn hiển thị output irq_rq , led 7 đoạn hiển thị vector_number. Em dùng 1 biến đếm count để đếm lên.
                      - Giả sử count đếm lên bằng 3 thì cho ngắt irq0, cho đèn led sáng trong 3s, sau đó clear thanh ghi trạng thái của ngắt này, khi đó output irq_rq và v_number bằng 0. Count = 8 thì cho ngắt irq1 và làm tương tự như ngắt trước.
                      - Vấn đề em gặp khó khăn là em làm sao tạo ra được bus để đưa ra các tín hiệu bus : sel, enable, w_enable, addr, data ... vào thiết kế. Trong thiết kế của em sẽ có module read_write_control nhận các tín hiệu này và thực hiện yêu cầu của CPU ( set độ ưu tiên, clear thanh ghi trạng thái...)
                      Chắc anh đã hiểu lầm ý của em, thiết kế của em là Interrupt chứ không phải là bộ đếm và đúng là em đang muốn làm 1 CPU giả lập để tạo ra các tín hiệu bus, nhưng còn nhiều chỗ mập mờ chưa thông được. Rất mong được a jefflieu và mọi người giúp đỡ. Em xin cám ơn

                      Comment


                      • #12
                        Nguyên văn bởi thanhth90 Xem bài viết
                        Em xin nói cụ thể thiết kế của em thế này:
                        - Em thiết kế 1 IP cores Interrupt Controller, IP của em có input gồm nhiều tín hiệu ngắt (nội và ngoại), output là 1 tín hiệu ngắt và 1 vector_number để định danh interrupt đang được thực hiện
                        - Các interrupt này sẽ được set độ ưu tiên bởi các thanh ghi priority, độ ưu tiên có thể thay đổi, tùy vào người lập trình.
                        - Em muốn hiện thực thiết kế của mình bằng cách đỗ code Verilog lên FPGA, dùng 1 led đơn hiển thị output irq_rq , led 7 đoạn hiển thị vector_number. Em dùng 1 biến đếm count để đếm lên.
                        - Giả sử count đếm lên bằng 3 thì cho ngắt irq0, cho đèn led sáng trong 3s, sau đó clear thanh ghi trạng thái của ngắt này, khi đó output irq_rq và v_number bằng 0. Count = 8 thì cho ngắt irq1 và làm tương tự như ngắt trước.
                        - Vấn đề em gặp khó khăn là em làm sao tạo ra được bus để đưa ra các tín hiệu bus : sel, enable, w_enable, addr, data ... vào thiết kế. Trong thiết kế của em sẽ có module read_write_control nhận các tín hiệu này và thực hiện yêu cầu của CPU ( set độ ưu tiên, clear thanh ghi trạng thái...)
                        Chắc anh đã hiểu lầm ý của em, thiết kế của em là Interrupt chứ không phải là bộ đếm và đúng là em đang muốn làm 1 CPU giả lập để tạo ra các tín hiệu bus, nhưng còn nhiều chỗ mập mờ chưa thông được. Rất mong được a jefflieu và mọi người giúp đỡ. Em xin cám ơn
                        Àh hiểu rồi

                        Mình nghĩ có 2 cách làm:
                        - Cách 1: Bạn làm một cái statemachine như mình nói, statemachine này đọc microcode từ on-chip ROM, lệnh của bạn có thể đơn giản có 40-bit như sau:
                        assign instruction = {opcode_2bit, address_6bit, data_32bit};
                        -----------------Statemachine sẽ đọc lệnh ra từ ROM và thực hiện các transaction: read/write vào các address và data tùy ý
                        -----------------Bạn sẽ phải viết một file để initialize con ROM, file này là binary, chứa các lệnh bạn muốn thưc hiện

                        - Cách 2: Bạn làm một bộ điều khiển
                        ------------ Một bên là các protocol có thể nối với máy tinh ví như Serial/Parallel
                        ------------ MỘt bên sẽ Bus Master nối với interrupt controller của bạn

                        Mình nghĩ còn nhiều phương thức khác tùy vào các phím trên board của bạn.

                        Comment


                        • #13
                          Anh có thể hướng dẫn cụ thể dùm em cách 1 được không ạ! Làm sao đưa đưa và lấy tín hiệu từ rom ? Tại sao mình không dùng Ram hay Sram mà phải dùng Rom vậy anh?

                          Comment


                          • #14
                            Nguyên văn bởi thanhth90 Xem bài viết
                            Anh có thể hướng dẫn cụ thể dùm em cách 1 được không ạ! Làm sao đưa đưa và lấy tín hiệu từ rom ? Tại sao mình không dùng Ram hay Sram mà phải dùng Rom vậy anh?
                            Gọi là ROM vì bạn không cần ghi vào lúc run-time (lúc mạch chạy thật) mà chỉ cần nạp data lúc compile (compile-time). Thực ra nó được thực hiện bằng tài nguyên BlockRAM hoặc LUT trên FPGA.
                            Bạn làm theo cái này : http://www.altera.com/literature/ug/ug_ram_rom.pdf, 2 phần chính:
                            -Parameter Setting
                            -Power-Up Conditions and Memory Initialization

                            Comment


                            • #15
                              Hic, cái user guide mà mod gửi rất ù ù cạc cạc (mấy bữa trước tìm cách làm LUT cho hàm arcsin nên biết). Mình diễn tả lại cách tạo LUT cho bạn thanhth90 dễ hiểu
                              1. Trong Quartus bạn tạo 1 cái file .mif (memory initial file) bằng 2 cách
                              - New/mif flie -->được 1 cái GUI do Quartus tạo sẵn, address có sẵn, các ô bit trừa trống, bạn muốn lưu gì thì gõ vô . Cách này không tiện lắm vì nhập data mệt hoặc là có cách nhập nhanh mà mình chưa biết
                              - New/text editor rồi save as file.mif. Data được nhập qua text editor này, theo 1 số nguyên tắc rất đơn giản như khai báo số hàng cần nhớ, số bit trong mỗi hàng, và data trong mỗi hàng. Nguyên tắc tạo mif ở đây: Memory Initialization File (.mif) Definition

                              2. vào file bdf của bạn insert/symbol/megafuntion wizard/ chọn cái ROM (hoặc RAM)/Create. Quartus sẽ hỏi các thông số của bộ nhớ như trong bước 1. Và cuối cùng Browse tới cái file mif bạn mới tạo bên trên để Quartus biết nó lấy data ở đâu.

                              3. xong rồi, đầu vào là address, đầu ra là data tương ứng bạn đã lưu trong file mif

                              Note : bạn có thể chọn ROM 1 hay 2 port, đơn giản chỉ là 1 addr/1out hoặc là 2addr/2out thôi

                              Comment

                              Về tác giả

                              Collapse

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

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

                              Collapse

                              Đang tải...
                              X