Thông báo

Collapse
No announcement yet.

Cần góp ý về đoạn code Verilog sau đây-mô phỏng trên kit DE2

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

  • Cần góp ý về đoạn code Verilog sau đây-mô phỏng trên kit DE2

    Mình viết 3 đoạn code như sau , mỗi đoạn code hoạt động như 1 máy trạng thái với xung CLOCK 50MHz dc cung cấp trên kit DE2 để tạo delay cho việc chuyển trạng thái tự động . Vấn đề mình gặp phải là mình muốn khi nào có tác động của các nút nhấn KEY[0] ,KEY[1] và KEY[2] trên kit DE2 thì các đoạn code tương ứng mới dc hoạt động . Tức là khi nhấn KEY[0] thì hoạt động đoạn code 1 , KEY[1] đoạn code 2 và KEY[2] đoạn code 3.Bạn nào rành về Verilog rất mong dc giúp đỡ đoạn này . Mình viết hoài mà ko chạy . Sau đây là 3 đoạn code của mình(chỉ trích đoạn thôi nhé)!Mời các bạn tham khảo :
    Đoạn 1 Khi bấm KEY[0] mình muốn thực hiện đoạn này)
    always @(posedge CLOCK_50)
    begin
    dem=dem+1;

    if(dem==1)
    begin
    LEDR[4]=1'b0;
    LEDR[3]=1'b1;
    LEDR[2]=1'b0;
    LEDR[1]=1'b1;
    LEDR[0]=1'b0;
    end
    if(dem==100000000)
    begin
    LEDR[4]=1'b1;
    LEDR[3]=SW[3];
    LEDR[2]=SW[2];
    LEDR[1]=SW[1];
    LEDR[0]=SW[0];
    end
    if(dem==125000000)
    begin
    LEDR[4]=1'b0;
    LEDR[3]=SW[3];
    LEDR[2]=SW[2];
    LEDR[1]=SW[1];
    LEDR[0]=SW[0];
    end
    if(dem==225000000)//delay them 2s
    begin
    LEDR[4]=1'b1;
    LEDR[3]=SW[3];
    LEDR[2]=SW[2];
    LEDR[1]=SW[1];
    LEDR[0]=SW[0];
    end
    if(dem==250000000)
    begin
    LEDR[4]=1'b0;
    LEDR[3]=SW[3];
    LEDR[2]=SW[2];
    LEDR[1]=SW[1];
    LEDR[0]=SW[0];
    end
    if(dem==350000000)//delay them 2s
    begin
    LEDR[4]=1'b1;
    LEDR[3]=1'b1;
    LEDR[2]=1'b0;
    LEDR[1]=1'b1;
    LEDR[0]=1'b1;
    end
    if(dem==375000000)
    begin
    LEDR[4]=1'b0;
    LEDR[3]=1'b1;
    LEDR[2]=1'b0;
    LEDR[1]=1'b1;
    LEDR[0]=1'b1;
    end
    if(dem==475000000)
    begin
    dem=0;
    LEDR[4]=1'b1;
    end

    end
    Đoạn code 2: (Khi bấm KEY[1] mình muốn làm đoạn này)
    always @(posedge CLOCK_50)
    begin
    dem=dem+1;

    if(dem==1)
    begin
    LEDR[4]=1'b0;
    LEDR[3]=1'b1;
    LEDR[2]=1'b0;
    LEDR[1]=1'b1;
    LEDR[0]=1'b0;
    end
    if(dem==100000000)
    begin
    LEDR[4]=1'b1;
    LEDR[3]=SW[7];
    LEDR[2]=SW[6];
    LEDR[1]=SW[5];
    LEDR[0]=SW[4];
    end
    if(dem==125000000)
    begin
    LEDR[4]=1'b0;
    LEDR[3]=SW[7];
    LEDR[2]=SW[6];
    LEDR[1]=SW[5];
    LEDR[0]=SW[4];
    end
    if(dem==225000000)//delay them 2s
    begin
    LEDR[4]=1'b1;
    LEDR[3]=SW[7];
    LEDR[2]=SW[6];
    LEDR[1]=SW[5];
    LEDR[0]=SW[4];
    end
    if(dem==250000000)
    begin
    LEDR[4]=1'b0;
    LEDR[3]=SW[7];
    LEDR[2]=SW[6];
    LEDR[1]=SW[5];
    LEDR[0]=SW[4];
    end
    if(dem==350000000)//delay them 2s
    begin
    LEDR[4]=1'b1;
    LEDR[3]=1'b1;
    LEDR[2]=1'b1;
    LEDR[1]=1'b0;
    LEDR[0]=1'b0;
    end
    if(dem==375000000)
    begin
    LEDR[4]=1'b0;
    LEDR[3]=1'b1;
    LEDR[2]=1'b1;
    LEDR[1]=1'b0;
    LEDR[0]=1'b0;
    end
    if(dem==475000000)
    begin
    dem=dem;
    LEDR[4]=1'b1;
    end

    end
    Đoạn code 3 cũng tương tự như vậy, chắc mình ko cần phải post lên.Mong anh em giúpđỡ để mình có thể kết hợp 3 đoạn code lại dc. Thank anh em trước !!(Ai có ý kiến khác xin chỉ bảo , mình rất mong dc các anh em giúpđỡ)

  • #2
    Rất mong nhận dc sự đóng góp và giúp đỡ từ phía anh em!!Cảm ơn anh em rất nhiều!!

    Comment


    • #3
      sao đoạn code này nhìn khiếp thể nhở.mình ko bàn đến cách bạn viet code nhé.nhưng mà nên viết lại cho gọn hơn.
      bạn dùng case cho bài này

      case (KEY) // KEY bạn khai báo gồm 3 bit nên verilog sẽ tự hiểu là KEY[2:0]
      3'b001: // truong hop nhan KEY[0]
      begin
      .....
      end
      3'b010: // truong hop nhan KEY[1]
      begin
      .....
      end
      3'b100: // truong hop nhan KEY[2]
      begin
      .....
      end
      default: //ban nen xet truong hop mặc định cho khỏi chạy sai
      begin
      .....
      end
      endcase

      cái này dùng if cũng ok

      if (KEY[0]) begin
      ......
      end
      else if (KEY[1]) begin
      ......
      end
      else if (KEY[2]) begin
      ......
      end
      else begin
      ....// cái này la trường hợp mặc định
      end

      Comment


      • #4
        Cái code trên chỉ có tác dụng với Slide Switches thôi chứ với Key Buttons thì ngay tại chu kỳ clock mà Key được nhả ra thì nó sẽ hoạt động theo phần default: Còn code dưới dung if thì tình hình còn tệ hơn vì sau đó chẳng có "phần code" nào được thực hiện nữa cả.

        Nếu vẫn muốn cố viết theo kiểu này bạn cần có 1 đoạn code để chốt Key press. Tuy nhiên mình nghĩ bạn nên thiết kế FSM theo đúng kiểu mà các trình Synthesis đều hỗ trợ. Việc thiết kế, quản lý chuyển trạng thái cũng như output sẽ dễ và rõ ràng hơn nhiều. Bạn có thể vào google search FSM coding style verilog

        Comment


        • #5
          Mình không rành về Verilog cho lắm, nhưng nếu structure của bạn là:
          if key[0]
          if dem = 0
          ...
          if dem = 100000000
          ........
          if key[1] .........
          if key[2] .........

          thì không được gọn cho lắm. Dù key = 0, 1, hoặc 2, bạn vẫn đếm y như vậy? Nếu vậy thì bạn nên gọp lại thành một đoạn đếm, và chỉ tùy theo key mà chọn LED output khác nhau. Cơ hội thành công của bạn sẽ cao hơn.

          Comment


          • #6
            Nguyên văn bởi manuk Xem bài viết
            sao đoạn code này nhìn khiếp thể nhở.mình ko bàn đến cách bạn viet code nhé.nhưng mà nên viết lại cho gọn hơn.
            bạn dùng case cho bài này

            case (KEY) // KEY bạn khai báo gồm 3 bit nên verilog sẽ tự hiểu là KEY[2:0]
            3'b001: // truong hop nhan KEY[0]
            begin
            .....
            end
            3'b010: // truong hop nhan KEY[1]
            begin
            .....
            end
            3'b100: // truong hop nhan KEY[2]
            begin
            .....
            end
            default: //ban nen xet truong hop mặc định cho khỏi chạy sai
            begin
            .....
            end
            endcase

            cái này dùng if cũng ok

            if (KEY[0]) begin
            ......
            end
            else if (KEY[1]) begin
            ......
            end
            else if (KEY[2]) begin
            ......
            end
            else begin
            ....// cái này la trường hợp mặc định
            end
            Cảm ơn bạn nhiều lắm nhưng đúng theo lời anh NEO nói , nếu viết theo cách này thì chỉ dùng cho SW dc mà thôi ( kích theo mức) - tức là khi nào mức 0 dc giữ luôn thì đoạn code mới dc hoạt động. Còn ý của mình là dùng KEY để kích cạnh xung cho code hoạt động(tức là đang tứ mức cao nhảy xuống mức thấp or ngược lại thì code sẽ hoạt động) Dù sao cũng cảm ơn bạn nhiều lắm!
            Last edited by achilles86; 02-05-2009, 19:13.

            Comment


            • #7
              Nguyên văn bởi NEO3F Xem bài viết
              Cái code trên chỉ có tác dụng với Slide Switches thôi chứ với Key Buttons thì ngay tại chu kỳ clock mà Key được nhả ra thì nó sẽ hoạt động theo phần default: Còn code dưới dung if thì tình hình còn tệ hơn vì sau đó chẳng có "phần code" nào được thực hiện nữa cả.

              Nếu vẫn muốn cố viết theo kiểu này bạn cần có 1 đoạn code để chốt Key press. Tuy nhiên mình nghĩ bạn nên thiết kế FSM theo đúng kiểu mà các trình Synthesis đều hỗ trợ. Việc thiết kế, quản lý chuyển trạng thái cũng như output sẽ dễ và rõ ràng hơn nhiều. Bạn có thể vào google search FSM coding style verilog
              Cảm ơn anh nhiều lắm ạ!!Do em mới tìm hiểu về Verilog nên chưa có kinh nghiệm và hiểu biết nhiều lắm!!Em sẽ cố tìm hiểu thêm!Mong dc các sư huynh có kinh nghiệm chỉ bảo thêm!!
              Last edited by achilles86; 02-05-2009, 18:48.

              Comment


              • #8
                Nguyên văn bởi nemesis21 Xem bài viết
                Mình không rành về Verilog cho lắm, nhưng nếu structure của bạn là:
                if key[0]
                if dem = 0
                ...
                if dem = 100000000
                ........
                if key[1] .........
                if key[2] .........

                thì không được gọn cho lắm. Dù key = 0, 1, hoặc 2, bạn vẫn đếm y như vậy? Nếu vậy thì bạn nên gọp lại thành một đoạn đếm, và chỉ tùy theo key mà chọn LED output khác nhau. Cơ hội thành công của bạn sẽ cao hơn.
                Cái mình muốn là xuất ra cùng output bạn ạ!!Nếu xuất riêng các LED ouput cho từng trường hợp thì mình làm dc rùi!!Dù sao cũng cảm ơn bạn!!

                Comment


                • #9
                  Vấn đề thứ 2 mình gặp phải là việc kiểm soát xung CLOCK_50 trên kit DE2 . Mình xin dc hỏi là việc dùng KEY để cho phép xung CLOCK hoạt động có dc ko? - Tức là khi nào bấm KEY thì xung CLOCK mới tác động cho biến "dem" tăng lên 1 . Biến "dem" vẫn tăng lên 1 theo xung CLOCK nhưng chỉ khi nào có KEY đã tác động ban đầu mà thôi!!!Huynh nào biết vấn đề nào xin chỉ giáo cho đệ với!!Thanks các huynh trước!!

                  Comment


                  • #10
                    Vấn đề ở chỗ là nếu làm riêng biệt thì có thể chạy tốt như bạn nói. Nhưng nếu có hơn một đoạn code cùng drive LED0/1/2/3/4 output thì sẽ gặp vấn đề multi-source. Nói đại khái là bạn không thể có parallel processes cùng drive 1 output được.

                    Lấy thí dụ đoạn code bên dưới. Syntax verilog có lẽ không chuẩn lắm, nhưng đại ý là đoạn code dưới illegal vì có 2 processes cùng drive output c.

                    Code:
                       always @ (posedge clk)
                       begin
                          count = count + 1;
                       end
                    
                       always @ (posedge clk)
                       begin
                          if (a == 1'b1)
                              if (count == 8'b11111111)
                                 c = 8'b1;
                       end
                    
                       always @ (posedge clk)
                       begin
                          if (b == 1'b1)
                              if (count == 8'b11111111)
                                 c = 8'b0;
                       end

                    Nên chỉnh lại để chỉ 1 process drive output c.

                    Code:
                       always @ (posedge clk)
                       begin
                          count = count + 1;
                       end
                    
                       always @ (posedge clk)
                       begin
                          if (count == 8'b11111111)
                             if (a == 1'b1)
                                c = 8'b1;
                             else if (b == 1'b1)
                                c = 8'b0;
                       end

                    Comment


                    • #11
                      Nguyên văn bởi achilles86 Xem bài viết
                      Vấn đề thứ 2 mình gặp phải là việc kiểm soát xung CLOCK_50 trên kit DE2 . Mình xin dc hỏi là việc dùng KEY để cho phép xung CLOCK hoạt động có dc ko? - Tức là khi nào bấm KEY thì xung CLOCK mới tác động cho biến "dem" tăng lên 1 . Biến "dem" vẫn tăng lên 1 theo xung CLOCK nhưng chỉ khi nào có KEY đã tác động ban đầu mà thôi!!!Huynh nào biết vấn đề nào xin chỉ giáo cho đệ với!!Thanks các huynh trước!!
                      Bạn nên dùng clock enable cho "dem", và biến đổi clock enable khi key được bấm.

                      Code:
                         always @ (posedge clk)
                         begin
                            if (clk_enable == 1b'1)
                              dem = dem+ 1;
                         end

                      Comment


                      • #12
                        Nguyên văn bởi nemesis21 Xem bài viết
                        Bạn nên dùng clock enable cho "dem", và biến đổi clock enable khi key được bấm.

                        Code:
                           always @ (posedge clk)
                           begin
                              if (clk_enable == 1b'1)
                                dem = dem+ 1;
                           end
                        Bác có thể cho em đoạn code biến đổi clock enable khi KEY dc bấm không ạ?Cảm ơn bác nhiều!!

                        Comment


                        • #13
                          Nguyên văn bởi achilles86 Xem bài viết
                          Bác có thể cho em đoạn code biến đổi clock enable khi KEY dc bấm không ạ?Cảm ơn bác nhiều!!
                          Số đếm chỉ tăng khi clock enable = 1, vậy khi key được nhấn xuống, clock enable nên chuyển thành 1. Đến khi bạn muốn ngừng đếm thì chuyển clock enable thành 0. Cũng tùy theo yêu cầu của bài tập. Chẳng hạn như nếu đang đếm mà một key khác được nhấn thì nên làm như thế nào?

                          Comment


                          • #14
                            Nguyên văn bởi nemesis21 Xem bài viết
                            Số đếm chỉ tăng khi clock enable = 1, vậy khi key được nhấn xuống, clock enable nên chuyển thành 1. Đến khi bạn muốn ngừng đếm thì chuyển clock enable thành 0. Cũng tùy theo yêu cầu của bài tập. Chẳng hạn như nếu đang đếm mà một key khác được nhấn thì nên làm như thế nào?
                            Theo như nemsis nói mình viết vậy dc ko nhỉ? Mong nemsis chỉ giáo...
                            always @(negedge KEY[0] or negedge KEY[1])
                            if(!KEY[0])
                            clk_enable=1'b1;
                            if(!KEY[1])
                            clk_enable=1'b0;
                            always @(posedge CLOCK_50)
                            begin
                            if(clk_enable==1'b1)
                            dem=dem+1;
                            else
                            dem=dem;
                            ...........................

                            Comment


                            • #15
                              Bạn nên vào link bên dưới (của Xilinx, nhưng phần lớn vẫn có thể áp dụng cho Altera), để tìm hiểu thêm về synchronous design:
                              http://www.smdp.iitkgp.ernet.in/PDF%..._tech_8new.pdf

                              Asynchronous process như của bạn dễ dẫn đến clock glitches (trang 9):
                              Code:
                              always @(negedge KEY[0] or negedge KEY[1])
                              Nên dùng synchronous process:
                              Code:
                              always @ (posedge clk)
                              hoặc:
                              Code:
                              always @ (negedge clk)
                              Và khi dùng clock enable, bạn không nên thêm else statement (trang 18).

                              Các trang sau đó đề cập đến chuyện chúng ta nên dùng synchronous reset thay vì asynchronous reset. Template cho synchronous reset (R) với clock enable (CE) cho Xilinx như sau (bạn nên thử lại với Altera cho chắc):

                              Code:
                              always @ (posedge clk)
                                if (reset == 1'b1)
                                  q = 1'b0;
                                else
                                  if (clk_en == 1'b1)
                                    q = d_in;
                              Last edited by nemesis21; 05-05-2009, 05:36.

                              Comment

                              Về tác giả

                              Collapse

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

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

                              Collapse

                              Đang tải...
                              X