Làm cách nào để cắt bớt độ rộng bit của biểu thức trong Verilog?


11

Hãy xem xét một biểu thức như:

assign x = func(A) ^ func(B);

trong đó đầu ra của func rộng 32 bit và x là một dây 16 bit. Tôi muốn chỉ gán 16 bit thấp nhất của xor kết quả.

Tôi biết đoạn mã trên đã làm điều đó, nhưng nó cũng tạo ra một cảnh báo. Cách tiếp cận "rõ ràng" không hoạt động:

assign x = (func(A) ^ func(B))[15:0]; // error: '[' is unexpected

Câu trả lời:


8

Bạn có thể sử dụng một biến khác, mặc dù điều này không đặc biệt thanh lịch.

wire[31:0] y;

assign y = func(A) ^ func(B);
assign x = y[15:0];

Một cách tiếp cận tốt hơn sẽ là sử dụng một chức năng.

function [15:0] trunc_32_to_16(input [31:0] val32);
  trunc_32_to_16 = val32[15:0];
endfunction

assign x = trunc_32_to_16(func(A) ^ func(B));

Tôi đã hy vọng sẽ có một cái gì đó đẹp hơn thế ... Ồ, tôi sẽ chỉ tạo ra một số lượng lớn các chức năng cắt ngắn.
dùng23106

5

Trong ví dụ của bạn, bạn đang ngầm cắt các bit.

Làm cho việc cắt ngắn rõ ràng thường có thể loại bỏ các cảnh báo trong mô phỏng / lint / tổng hợp.

Một cách để thực hiện việc này là sử dụng toán tử cast, ví dụ:

typedef logic [15:0] HALF_WORD;
assign x = HALF_WORD'((func(A) ^ func(B));

Cách tiếp cận này có thể có ý nghĩa nếu rõ ràng từ bối cảnh rằng tất cả các bit bị loại bỏ là 0.

Nếu một số bit có thể khác 0 thì tôi khuyên bạn vẫn nên sử dụng mạng trung gian như @dwikle đã đề xuất trong câu trả lời trước , vì nó làm rõ hơn rằng bạn thực sự đang vứt bỏ bit. Đây là một lần nữa để tham khảo.

wire[31:0] y;

assign y = func(A) ^ func(B);
assign x = y[15:0];

1
Tôi nghĩ rằng nó sẽ chỉ hoạt động trong SystemVerilog. Thú vị không kém.
Tom Carpenter

@TomCarpenter, bạn có muốn giới hạn bản thân mình trong tập hợp con Verilog có sẵn trong IEEE Std 1364-2005, thay vì sử dụng bộ phiên bản tổng hợp đầy đủ có sẵn trong một trong các phiên bản mới nhất của IEEE Std 1800 không? Bạn có thể muốn nói Verilog-2005 hoặc một cái gì đó để làm rõ, vì tiêu chuẩn Verilog đã được đưa vào tiêu chuẩn SystemVerilog hợp nhất vào năm 2009.
rõ ràng là

3

Tôi nghĩ rằng điều này có thể giúp giữ cho dòng đếm ngược.

wire [15:0] not_used ;

assign {not_used, x} = (func(A) ^ func(B));

Không chắc chắn nếu điều đó là hợp lệ với chuyển nhượng mặc dù.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.