Thông báo

Collapse
No announcement yet.

Cần anh em sửa giúp cho đoạn code Verilog sau

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

  • Cần anh em sửa giúp cho đoạn code Verilog sau

    Sau 1 thời gian mình cố viết code để lưu giá trị vào ram ko thành công ( Gà ),mình đã thử sử dụng lưu giá trị vào mảng.Ý tưởng của code mình như sau : Dùng KEY[3] để tăng giá trị 1 biến(Y4Y5) . Khi bấm KEY[0] thì sẽ xuất ra giá trị Y8Y9=Y0Y1 đồng thời tăng giá trị 1 biến (Y0Y1 nếu Y0Y1<Y4Y5 . Nếu Y0Y1>Y4Y5 thì bấm KEY[0] sẽ không tăng Y0Y1 và Y8Y9 sẽ bằng Y2Y3 với giá trị Y2Y3 dc truy xuất ra từ mảng . Bấm KEY[1] sẽ lưu Y8Y9 vào mảng .

    Ví dụ : Khi bấm KEY[3] cho Y4Y5 đến giá trị là 6
    Ta bấm KEY[0] cho Y0Y1 lên đến 2 rùi bấm KEY[1] lần 1
    Bấm tiếp KEY[0] cho Y0Y1 lên 4 ta lại bấm KEY[1]
    Bấm KEY[0] cho Y0Y1 lên 5 ta lại bấm KEY1
    Tiếp tục bấm KEY[0] cho Y0Y1 lên tiếp qua 6 (>Y4Y5) lúc này việc bấm KEY[0] sẽ xuất ra giá trị lưu tại mảng tức là các số 2 4 5 sau 3 lần bấm KEY[0]. Tuy nhiên đoạn code mình viết nó lại xuất ra giá trị 0 2 4 5 sau 4 lần bấm KEY[0] . Mong các sư huynh chỉ giáo giúp . Em xin cảm ơn . Sau đây là đoạn code của đệ :


    Code:
    module ram2705(KEY,HEX7,HEX6,HEX5,HEX4);
    input [3:0]KEY;
    output [6:0]HEX4,HEX5,HEX6,HEX7;
    reg [7:0]mem[100:1];
    integer add_write,add_read;
    reg [3:0]Y0,Y1,Y2,Y3,Y4,Y5,Y8,Y9;
    reg [7:0]Y6,Y7;
    reg [7:0]Y10;
    
    always @(negedge KEY[3])
    	begin
    		Y4=Y4+1;
    			if(Y4>9)
    				begin
    					Y4=0;
    					Y5=Y5+1;
    				end
    	end
    always @(negedge KEY[0])
    	begin
    		Y6=Y5*10+Y4;
    		Y7=Y1*10+Y0;
    		if(Y6>Y7)
    			begin
    				Y0=Y0+1;
    				Y8=Y0;
    				Y9=Y1;
    					if(Y0>9)
    						begin
    							Y0=0;
    							Y1=Y1+1;
    							Y8=Y0;
    							Y9=Y1;
    						end
    			end
    		else
    			begin
    				Y8=Y2;
    				Y9=Y3;
    				Y0=Y0;
    				Y1=Y1;
    				if(add_write>add_read||add_write==add_read)
    					begin
    						Y10=mem[add_read];
    						add_read=add_read+1;
    						Y3=Y10[7:4];
    						Y2=Y10[3:0];
    					end
    				else
    					begin
    						add_read=add_read;
    					end
    			end
    	end
    
    always @(negedge KEY[1])
    	begin
    		add_write=add_write+1;
    		mem[add_write]={Y9,Y8};
    	end
    
    hienthi(Y5,HEX7);
    hienthi(Y4,HEX6);
    hienthi(Y9,HEX5);
    hienthi(Y8,HEX4);
    endmodule
    module hienthi(c,display);
    input [3:0]c;
    output reg [0:6]display;
    always @(c)
    	case(c)	
    		4'd0:display=7'b1000000;
    		4'd1:display=7'b1111001;
    		4'd2:display=7'b0100100;
    		4'd3:display=7'b0110000;
    		4'd4:display=7'b0011001;
    		4'd5:display=7'b0010010;
    		4'd6:display=7'b0000010;
    		4'd7:display=7'b1111000;
    		4'd8:display=7'b0000000;
    		4'd9:display=7'b0010000;
    		default:display=7'b1111111;
    	endcase
    endmodule
    Mô phỏng dạng sóng nè!!Các bạn sẽ thấy khi bấm KEY[0] qua 6 nó sẽ xuất giá trị lần lượt là 0 2 4 5 . Nhờ các huynh giúp bỏ đi số 0 để xuất dc giá trị là 2 4 5 mà thôi . Thank các huynh nhiều lắm ạ .Hjx hjx

  • #2
    Là vì cái này:

    Code:
    always @(negedge KEY[0])
    	begin
    		Y6=Y5*10+Y4;
    		Y7=Y1*10+Y0;
    		if(Y6>Y7)
    			begin
    				Y0=Y0+1;
    				Y8=Y0;
    				Y9=Y1;
    					if(Y0>9)
    						begin
    							Y0=0;
    							Y1=Y1+1;
    							Y8=Y0;
    							Y9=Y1;
    						end
    			end
    		else
    			begin
    				Y8=Y2;
    				Y9=Y3;
    				Y0=Y0;
    				Y1=Y1;
    				if(add_write>add_read||add_write==add_read)
    					begin
    						Y10=mem[add_read];
    						add_read=add_read+1;
    						Y3=Y10[7:4];
    						Y2=Y10[3:0];
    					end
    				else
    					begin
    						add_read=add_read;
    					end
    			end
    	end

    Thế nàyY8, Y9 dùng làm đầu vào giải mã hiển thị sẽ được dịch thành 1 thanh ghi và cập nhật giá trị tại sườn của KEY(0). Khi mà KEY(0) được ấn/nhả và Y6 = Y7 +1 ( tức là lúc vừa hết hàng đợi ) thì Y8, Y9 thực chất sẽ nhận giá trị của Y2, Y3 ban đầu ( ko phải giá trị được lấy ra từ bộ nhớ ) nên nó sẽ là 0.

    => giải pháp là vất cái đoạn gán Y8, Y9 với {Y1,Y0} và {Y2,Y3} ra ngoài block bắt theo sườn ( nedge hay posedge ) để nó là mạch combinational mux thuần túy

    PS: em nên có phần mạch điều khiển việc khởi tạo cái giá trị dữ liệu và tín hiệu điều khiển ( nếu có ) cho mạch để đảm bảo mạch hoạt động an toàn. VD trong trường hợp code của em addread với addwrite ko đc khởi tạo nên ko có điều kiện ràng buộc explicit. Vả {Y3,Y2} nữa.

    Comment


    • #3
      Em đã thử bỏ đoạn gán ra và viết 1 block riêng như ở dưới nhưng tình trạng vẫn bị vậy anh ơi!!
      Code:
      always @(negedge KEY[0])
      	begin
      		if(Y6>Y7)	
      			begin
      				Y8=Y0;
      				Y9=Y1;
      			end
      		else
      			begin
      				Y8=Y2;
      				Y9=Y3;
      			end
      	end
      Em nghĩ chắc do em luôn gán Y2Y3 là đọc dữ liệu từ mảng ra , mà khi nào có KEY[1] thì mới ghi Y0Y1 vào mảng nên trước đó Y2Y3 luôn lấy giá trị là 00 và khi xuất ra nó sẽ xuất ra giá trị 00 . Không biết có phải ko ạ?Mong anh chỉ giáo thêm. Cảm ơn anh!
      Last edited by achilles86; 29-05-2009, 01:03.

      Comment


      • #4
        Nguyên văn bởi achilles86 Xem bài viết
        Em đã thử bỏ đoạn gán ra và viết 1 block riêng như ở dưới nhưng tình trạng vẫn bị vậy anh ơi!!
        Code:
        always @(negedge KEY[0])
        	begin
        		if(Y6>Y7)	
        			begin
        				Y8=Y0;
        				Y9=Y1;
        			end
        		else
        			begin
        				Y8=Y2;
        				Y9=Y3;
        			end
        	end
        Chính cái này là cái tạo ra lỗi. Ý anh là những j em vất trong 1 áci always@(negedge ... ) sẽ tạo ra flip-flops. Em có thể sửa thành thế này:

        Code:
        always @(Y0,Y1,Y2,Y3,Y6,Y7)
        	begin
        		if(Y6>Y7)	
        			begin
        				Y8=Y0;
        				Y9=Y1;
        			end
        		else
        			begin
        				Y8=Y2;
        				Y9=Y3;
        			end
        	end
        Em nghĩ chắc do em luôn gán Y2Y3 là đọc dữ liệu từ mảng ra , mà khi nào có KEY[1] thì mới ghi Y0Y1 vào mảng nên trước đó Y2Y3 luôn lấy giá trị là 00 và khi xuất ra nó sẽ xuất ra giá trị 00 . Không biết có phải ko ạ?Mong anh chỉ giáo thêm. Cảm ơn anh!
        Code của em sẽ gán Y2Y3 là đọc dữ liệu từ mảng ra chỉ khi

        (Y6<=Y7)&(add_write>add_read||add_write==add_read)

        Còn lại nó sẽ giữ nguyên giá trị (mà ở đây nó sẽ được coi là 0. Thực tế nó có thể là UNKNOWN vì ko có giá trị khởi tạo)

        Comment


        • #5
          Em đã thử như anh nói nhưng nó vẫn bị tình trạng đó anh ạ.Hjx hjx

          Comment


          • #6
            ah cái đấy là do phần cục này
            Code:
            always @(negedge KEY[1])
            	begin
            		add_write=add_write+1;
            		mem[add_write]={Y9,Y8};
            	end
            Thế này thì em bắt đầu ghi ở địa chỉ 1 trong khi lại bắt đầu đọc từ địa chỉ 0 nên tất nhiên là sẽ đọc đc giá trị 0 ( tại địa chỉ 0 )
            => chuyển thành thế này

            Code:
            always @(negedge KEY[1])
            	begin
            		mem[add_write]={Y9,Y8};
            		add_write=add_write+1;
            	end

            Comment


            • #7
              Thank anh NEO rất nhiều ... Code đã chạy tốt rùi anh ạ...Anh quả là cao thủ , đàn em bái phục,bái phục..hjhj

              Comment


              • #8
                ai có code viết về hiển thị lên LCD, chip EPM204GT không, cho mình xin với .mail: davix.ba@gmail.com ,thank!

                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