使用多路复用器的双向移位 [英] Bidirectional shifting using multiplexers
问题描述
编辑:仅通过屏幕截图(http://prntscr.com/lv3uqwhttp://prntscr.com/lv3yhf)和我下面的代码,您仍然可以在这里理解我的目标,以防您不想阅读文本。
我正在尝试为通用移位寄存器编写verilog代码。我的原始寄存器工作正常(没有LR_bar signal
的那个)。但在这个问题上,我不知道如何实现这种连接(Mux With Ff)http://prntscr.com/lv3uqw,http://prntscr.com/lv3yhf.I建议for循环应该从-1开始,但我仍然找不到解决方案。如果可能的话,我也想避免使用h信号(也许我们在那里也用w)。因此,基本上当LR_bar=1
我希望移位寄存器shift left
时,以及当=0
到shift right
时。
截图提示:l_sh中的Ser代表左移的串口
(还发现在Mano Morris第3版(第6版更详细)上)的书(计算机设计基础),在某种程度上,有点接近我想要的。但我想要2比1的多路复用器。但前两张截图是我想要实现的。 http://prntscr.com/lvb5bthttp://prntscr.com/lvb65f)
我想我描述得很好...有人能解决这个问题吗?
我的新代码(如下)和一些值之后的测试......http://prntscr.com/lvhk63
我试图模仿(http://prntscr.com/lvgx31http://prntscr.com/lvgxgwhttp://prntscr.com/lvgxkw),但仅针对串口输入部分(MSB、LSB)。请告诉我我哪里弄错了。感谢
输出应为寄存器的状态
-----------------------------------------------------------
module lr_shreg_n(in, out, clk, rst, LR_bar);
parameter n=4;
input in, rst, clk, LR_bar;
output [n-1:0] out;
wire [n+1:0] w;
wire [n-1:0] mux_out;
genvar i;
assign w[0]=in;
assign w[n+1]=in;
generate
for(i=0;i<n;i=i+1)
begin
mux2to1 MUX(.in({w[i],w[i+2]}),.sel(LR_bar),.out(mux_out[i]));
dff ff1(.d(mux_out[i]), .q(w[i+1]), .clk(clk),
.rst(rst));
end
endgenerate
assign out=w[n:1];
endmodule
------------------------------------------------------------
JUST AN ATTEMPT NOTHING TO LOOK
module lr_shreg_n(in, out, clk, rst, LR_bar);
parameter n=4;
input in, rst, clk, LR_bar;
output [n-1:0] out;
wire [n+1:0] w;
wire mux_out;
genvar i;
assign w[0]=in;
assign w[n+1]=in;
generate
for(i=-1;i<n-1;i=i+1)
begin
mux2to1 MUX(.in({w[i+1],w[3+i]}),.sel(LR_bar),.out(mux_out));
dff ff1(.d(mux_out), .q(out[i+1]), .clk(clk),
.rst(rst));
end
endgenerate
------------------------------------------------------------
module dff (d, q, clk, rst);
input d, clk, rst;
output reg q;
always @ (posedge clk) begin : dff_block
if (rst==1'b1)
q = 1'b0;
else
q = d;
end
endmodule
module mux2to1(in, sel, out) ;
input [1:0] in;
input sel;
output reg out;
always @(*)
case(sel)
1'b0: out=in[0];
1'b1: out=in[1];
endcase
endmodule
module shreg_n(in, out, clk, rst);
parameter n=4;
input in, rst, clk;
output [n-1:0] out;
wire [n:0] w;
genvar i;
assign w[0]=in;
generate
for(i=0;i<n;i=i+1)
dff ff1(.d(w[i]), .q(w[i+1]), .clk(clk),
.rst(rst));
endgenerate
assign out=w[n:1];
//assign out=w[n];
endmodule
推荐答案
阻止分配可能适用于您的特定案例。为了保持清晰的编码风格,并防止将来出现任何问题,请始终使用<=
作为Flop(和锁存器)中的所有输出分配。
现在,让我们看看您想要做什么:
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]
因此,对于多路复用器,比如说out[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[i]);
基本上它为这些特殊情况创建了另一个多路复用器,因此您有更多的特殊情况。
至于失败,至少有两种方法可以接近它。您可以在多路复用器之前或之后更改结果。
对于多路复用器之前的失败(我在上面的解释中假定了这一点),您只需
always @(posedge clk)
if (rst)
w <= 4'b0;
else
w <= out;
要在多路复用器之后执行此操作,您需要将out
和w
切换到w
,然后将w
切换为out
。你可以像你做的那样一点一点地失败,但在我看来,这让程序变得更加拥挤。此外,它还会导致verilog生成多个1位触发器,这可能会影响模拟性能。
使用触发器的移位寄存器的另一种方法如下所示:
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
将复用器与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
这篇关于使用多路复用器的双向移位的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!