我想通过从任意位置切割一位,使输出总线比输入短1位,如下所示:
module jdoodle;
integer i;
reg [8:0] in;
reg [7:0] out;
reg [3:0] idx;
always @*
begin
case(idx)
0: out = in[8:1];
1: out = {in[8:2], in[0]};
2: out = {in[8:3], in[1:0]};
3: out = {in[8:4], in[2:0]};
4: out = {in[8:5], in[3:0]};
5: out = {in[8:6], in[4:0]};
6: out = {in[8:7], in[5:0]};
7: out = {in[8], in[6:0]};
default: out = in[7:0];
endcase
end
initial begin
in = 9'b010101010;
for (i = 0; i < 9; i++)
begin
idx = i; #10;
$display ("%x - %08b", idx, out);
end
$finish;
end
endmodule
我找到了一种写在一行中的方法:
module jdoodle;
integer i;
reg [8:0] in;
reg [3:0] idx;
wire [7:0] out;
assign out = ((in >> 1) & (16'h00ff << idx)) | (in & (16'hff00 >> (16-idx)));
initial begin
in = 9'b010101010;
for (i = 0; i < 9; i++)
begin
idx = i; #10;
$display ("%x - %08b", idx, out);
end
$finish;
end
endmodule
但它的可读性不如第一个,但第一个对更大的公交车来说相当糟糕。有更优雅的方法吗?还有标准的verilog库,比如std for c++,包含像任意旋转这样的通用模块吗?
感谢
编辑:这是预期的输出:
0 - 01010101
1 - 01010100
2 - 01010110
3 - 01010010
4 - 01011010
5 - 01001010
6 - 01101010
7 - 00101010
8 - 10101010
您可以使用循环处理每个位:
module jdoodle #(parameter INW = 'd9)
(
input [INW-1:0] in,
output[INW-2:0] out,
input [$clog2(INW)-1:0] idx
);
always_comb begin
for(int i = 0; i<INW; i++) begin
if (i < idx) out[i] = in[i];
else if (i > idx) out[i-1] = in[i];
// do nothing if i == idx
end
end
endmodule