Двунаправленное смещение с использованием мультиплексоров - PullRequest
0 голосов
/ 15 декабря 2018

Редактировать: Только по скриншотам (http://prntscr.com/lv3uqw http://prntscr.com/lv3yhf) и моему коду ниже вы все еще можете понять мою цель, только если вы не хотите читать текст.

Iя пытаюсь написать код verilog для универсального регистра сдвига. Мой оригинальный регистр работал правильно (тот, у которого нет LR_bar signal). Но на этом я не знаю, как я могу сделать это соединение (MUX с FF), чтобы http://prntscr.com/lv3uqw и http://prntscr.com/lv3yhf.I предположили, что цикл for должен начинаться с -1, но я все еще не могу найти решение. Я также хотел бы избежать сигнала h, если это возможно (возможно, мы также используем wтак что в основном, когда LR_bar=1 я хочу, чтобы регистр сдвига был shift left, а когда =0 - shift right.

Совет для скриншота: ser в l_sh обозначает последовательный ввод для сдвига влево

(Также обнаружено, что в 3-м издании Мано Морриса (6-е более подробно) книга (Основы компьютерного дизайна), которая, в некотором смысле, немного близка к тому, что я хочу. Но я хочу мультиплексоры 2to1. Но2 первый скриншотэто то, чего я хочу достичь.http://prntscr.com/lvb5bt http://prntscr.com/lvb65f)

Я думаю, что я хорошо это опишу ... может кто-нибудь решить эту проблему?

МОЙ НОВЫЙ КОД (ниже) И ТЕСТ ПОСЛЕ НЕКОТОРЫХ ЗНАЧЕНИЙ...... http://prntscr.com/lvhk63

Я пытался имитировать, что (http://prntscr.com/lvgx31 http://prntscr.com/lvgxgw http://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

1 Ответ

0 голосов
/ 15 декабря 2018

Блокировка назначений может работать в вашем конкретном случае.В целях чистого стиля кодирования и предотвращения любых проблем в будущем всегда используйте <= для всех выходных назначений на флопах (и защелках).

Теперь давайте посмотрим, что вы хотите сделать:

 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
...