Блокировка назначений может работать в вашем конкретном случае.В целях чистого стиля кодирования и предотвращения любых проблем в будущем всегда используйте <=
для всех выходных назначений на флопах (и защелках).
Теперь давайте посмотрим, что вы хотите сделать:
w = out; // to keep the immediate values and avoid ordering issues
for left shift: w[3] -> x, w[2] -> out[3], w[1] -> out[2], w[0] -> out[1] , in -> out[0]
for right shift: w[0] -> x, w[1] -> out[0], w[2] -> out[1], w[3] -> out[2], in -> out[3]
так что с мультиплексором, скажем, для [2] i == 2
, вам понадобится мультиплексор, который делает это:
- w[1] -
-> out[2]
- w[3] -
mux2to1 (.in({out[i+1], out[i-1]}), .sel(LR_sel), .out(out[i]));
вам также нужно позаботиться о специальных случаях [0] со смещением влево и [n-1] со смещением вправо.Для простоты вы можете использовать оператор if
в блоке генерации для его обработки.
if (i == 0)
mux2to1 MUX0(.in({in, w[1]}), .sel(LR_bar), .out(tmp[0]));
else if (i == n-1)
mux2to1 MUXN(.in({w[n-2], in}), .sel(LR_bar), .out(tmp[n-1]));
.out (out [i]));иначе mux2to1 (.in ({out [i-1], out [i + 1]}), .sel (LR_sel), .out (out [i]));
По сути, это создает еще одинМюкс для тех особых случаев, чтобы у вас их было больше.
Что касается флопа, есть как минимум 2 способа приблизиться к нему.Вы можете получить результаты до или после мультиплексирования.
для флопинга до мультиплексирования (что я и предполагал в приведенном выше объяснении), вы просто делаете
always @(posedge clk)
if (rst)
w <= 4'b0;
else
w <= out;
, чтобы сделать это после мультиплексированияВам нужно было бы переключить out
и w
, а затем поставить w
на out
.Вы можете делать пошаговый флоп, как и вы, но, на мой взгляд, это делает программу более насыщенной.Также это заставляет verilog генерировать несколько однобитовых флопов, которые могут повлиять на производительность симуляции.
Еще один подход для сдвиговых регистров с флопом заключается в следующем:
always @(posegde clk) begi
if (rst)
out <= 4'b0;
else if (LR_bar) begin
out <= {out[2:0], in};
end
else begin
out <= {in, out[3:1]};
end
end
Вышеприведенный код значительно упрощает код.Кстати, у вас возникнет проблема, если вы будете использовать там блокирующие назначения.
Редактировать 1
Я изменил ваш код до работоспособного состояния здесь, основываясь на моих комментариях.вам нужен регистр w
, чтобы сохранить значение регистра сдвига.Вам нужен tmp
для соединения mux с flop .w
является выходом флопа.
module uni_shreg_n(in, out, clk, rst, LR_bar);
parameter n=4;
input in, rst, clk, LR_bar;
output [n-1:0] out;
reg [n-1:0] w; // keep the value of the register shift
wire [n-1:0] tmp;
genvar i;
mux2to1 MUX0(.in({in,w[1]}), .sel(LR_bar), .out(tmp[0]));
mux2to1 MUXN(.in({w[n-2], in}), .sel(LR_bar), .out(tmp[n-1]));
generate
for(i=0;i<n;i=i+1) begin
if (i > 0 && i < n-1) begin: loop
mux2to1 MUX(.in({w[i-1], w[i+1]}), .sel(LR_bar), .out(tmp[i]));
end
dff ff1(.d(tmp[i]), .q(w[i]), .clk(clk), .rst(rst));
end
endgenerate
assign out = w;
endmodule