使用多路复用器的双向移位 [英] Bidirectional shifting using multiplexers

查看:6
本文介绍了使用多路复用器的双向移位的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑:仅通过屏幕截图(http://prntscr.com/lv3uqwhttp://prntscr.com/lv3yhf)和我下面的代码,您仍然可以在这里理解我的目标,以防您不想阅读文本。

我正在尝试为通用移位寄存器编写verilog代码。我的原始寄存器工作正常(没有LR_bar signal的那个)。但在这个问题上,我不知道如何实现这种连接(Mux With Ff)http://prntscr.com/lv3uqwhttp://prntscr.com/lv3yhf.I建议for循环应该从-1开始,但我仍然找不到解决方案。如果可能的话,我也想避免使用h信号(也许我们在那里也用w)。因此,基本上当LR_bar=1我希望移位寄存器shift left时,以及当=0shift 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;
要在多路复用器之后执行此操作,您需要将outw切换到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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆