2013-05-07 37 views
10

Vì vậy, nó đã kết thúc rằng các lỗi đã giữ tôi trong nhiều ngày, là một phần của mã nên đánh giá để đánh giá sai để True. mã ban đầu của tôi đã đi một cái gì đó như:Sự khác biệt giữa Verilog! và ~?

if(~x && ~y) begin 
    //do stuff 
end 

ví dụ: Nếu x là KHÔNG MỘT và y là KHÔNG MỘT sau đó làm công cụ. Bước qua trình gỡ lỗi, tôi nhận ra ngay cả khi x là 1 biểu thức trong câu lệnh if vẫn dẫn đến TRUE và mã tiếp theo được thực thi.

Tuy nhiên, khi tôi thay đổi tuyên bố:

if(x == 0 && y == 0) begin 
//do stuff 
end 

và cũng đã cố gắng:

if(!x && !y) begin 
//do stuff 
end 

mã trong if-tuyên bố không được đánh giá đó là hành vi mong đợi. Tôi hiểu rằng ~ là một sự phủ nhận bitwise và! một phủ định hợp lý, nhưng không nên (~ x & & ~ y) và (! x & &! y) đánh giá điều tương tự? Tôi sợ codebase quá lớn, vì vậy tôi không thể dán nó ở đây, nhưng đây là thay đổi duy nhất tôi thực hiện để làm cho mã hoạt động như tôi dự định. Cảm ơn.


Để đáp lại, với một trong các ý kiến ​​dưới đây, tôi đã tạo ra một thử nghiệm hợp cụ thể để kiểm tra hành vi này:

'10ns khoảng thời gian/1ns

mô-đun test_negation();

integer x, y; 

initial begin 
    x = 1; y = 0; 

    if(~x && ~y) begin 
     $display("%s", "First case executed"); 
    end 

    if(!x && !y) begin 
     $display("%s", "Second case executed"); 
    end 

    if(x == 0 && y == 0) begin 
     $display("%s", "Third case executed"); 
    end 
end endmodule 

Điều lạ lùng là, "Trường hợp đầu tiên thực hiện" được in để xác nhận hành vi ban đầu tôi quan sát.

+0

đoán, nhưng không phủ định bitwise sẽ giống như '~ 0xAA = 0x55', v.s. '! 0xAA' là tương đương với" 0xAA không phải là 0, do đó đánh giá là đúng ". –

+0

@Marc B Vâng, đó là một sự khác biệt quan trọng. Tuy nhiên trong trường hợp này, cả x và y dài 1 bit. Nếu x là "1", tôi mong đợi một sự phủ định bitwise ~ x là "0" .. – iab

+0

Một chút dài? Thật lạ lùng. Bạn có thể thực hiện một dự án thử nghiệm để hiển thị các giá trị của 'x','! X', '~ x',' y', '! Y',' ~ y', và '(~ x && ~ y)' và '(! x &&! y)'? –

Trả lời

13

Biểu tượng ! biểu thị sự phủ định boolean hoặc logic. Đối với bất kỳ giá trị nào của x khác 0, !x đánh giá là không hoặc sai và khi x bằng 0, !x đánh giá thành một hoặc đúng.

Biểu tượng ~ thể hiện sự phủ định bitwise. Mỗi bit trong giá trị được bật, do đó, đối với x == 0xA5A5 16 bit, ~x sẽ đánh giá là 0x5A5A.

if() có điều kiện mong đợi một biểu thức đánh giá đúng hoặc sai, trong đó bất kỳ thứ gì khác không phải (dương hoặc âm) là đúng và số không là false.

&& là logic AND. Phải mất hai biểu thức, đánh giá thành một hoặc đúng nếu và chỉ khi cả hai biểu thức là đúng. Một lần nữa, "true" ở đây có nghĩa là nonzero, dương hoặc âm.

Với tất cả điều này, chúng ta có thể thấy rằng thời gian chỉ ~x!x đánh giá với giá trị tương tự là khi x == -1, hoặc, nếu x là unsigned, khi x == MAX_UNSIGNED.

+0

Tôi đã thêm dự án thử nghiệm vào bài đăng gốc. Cùng một hành vi được quan sát! – iab

+0

Bao nhiêu bit là số nguyên mặc định? ~ 1 == 0xFFFE và ~ 0 == 0xFFFF, vì vậy ví dụ đó có ý nghĩa. –

+1

Thật không may phức tạp hơn nhiều so với điều này (tôi thấy ai đó vừa nhấp vào câu trả lời của bạn). Lời giải thích của bạn về '!' Không chính xác - kết quả là 3 trạng thái ('1',' 0', 'x') và'! X' cũng là 'x'. Trong đoạn 2, thường khó có thể quyết định độ rộng của biến số, điều này có thể dẫn đến những bất ngờ. Đối với đoạn 3, bạn phải tính đến 'x'. Đối với đoạn 4, định nghĩa của bạn về 'true' là không chính xác - nó phải không khác và đã biết. Và cứ thế. – EML

2

~ là nhà khai thác bit-khôn ngoan và trả về đảo ngược đối số.

! là toán tử logic và trả về một bit.

Ví dụ:

reg [7:0] bit_wise, logic_op; 
initial begin 
    bit_wise = ~8'hA1; // bit_wise == 8'h6E 
    logic_op = !8'hA1; // logic_op == 8'b00 
    $display("bit_wise:%h logic_op:%h", bit_wise, logic_op); // bit_wise:5e logic_op:00 
end 

Ví dụ của bạn:

if(~x && ~y) begin 
    //do stuff 
end 

là có hiệu quả tương tự như:

if(x!='1 && y!='1) begin // '1 means the with of x all 1s and the with of y all 1s 
    //do stuff 
end 

Nói chung phong cách mã hóa tốt nhất là sử dụng toán tử logic bên trong câu lệnh if . Chỉ sử dụng toán tử bit-khôn ngoan với thao tác gán dữ liệu.

+0

FYI - Cú pháp ''1' không phải là cú pháp Verilog hợp lệ. Cấu trúc này đã được giới thiệu trong SystemVerilog. – dwikle

+0

Không biết chiều rộng của 'x' và' y', tôi đã quyết định sử dụng cú pháp SystemVeilog và đặt ghi chú giải thích cái ''1' nào được dùng cho. Kể từ khi phát hành IEEE Std 1800-2009, Verilog và SystemVerilog là một và cùng một . (Đề cập trong phần tóm tắt, có thể ai đó khác có thể tìm thấy trích dẫn tốt hơn.) – Greg

+0

Việc sử dụng ~ trong câu lệnh if không rõ ràng. Tôi sẽ luôn luôn sử dụng ~ với một so sánh. Ngoài ra giả lập của tôi không nghĩ rằng Verilog và SystemVerilog là cùng một điều. Verilog thường được sử dụng để tham khảo các thông số kỹ thuật 1995 hoặc 2001 trước khi SystemVerilog nó làm cho một sự khác biệt lớn cho những người sử dụng công cụ cũ. – Morgan

4

Tôi hiểu. Biến "x" trong mã trên là một số nguyên Verilog (integer x;). Tuy nhiên, số nguyên được Verilog đại diện dưới dạng số nguyên 32 bit. Vì vậy, mặc dù x là "1" như tôi đã quan sát, ~ x sẽ không dẫn đến "0" nhưng trong "11111111111111111111111111111110"! Và do đó, không có gì ngạc nhiên khi Trường hợp đầu tiên được thực hiện. Lỗi của tôi. Cảm ơn tất cả các câu trả lời.

+0

Câu hỏi hay và bạn đã tự mình có được câu trả lời đúng. – EML

+0

Rất vui khi bạn làm việc đó. Bài học này là sử dụng các loại 'reg' &' wire' trong Verilog cổ điển, hoặc các kiểu 'bit' &' logic' trong Verilog hiện đại và kích thước tín hiệu của bạn một cách thích hợp. (Được cảnh báo, những loại đó không tương đương) –

Các vấn đề liên quan