串行器 32 到 8 - Verilog HDL

Serializer 32 to 8 - Verilog HDL

我正在尝试将序列化程序从 32 位转换为 8 位。因为我刚开始使用 verilog,所以我遇到了问题。我想获得 32 位(每 4 个时钟周期),然后在每个时钟周期发送 8 位。我怎样才能只获取我的数据输入的一部分,我在下面编写了代码,但赋值表达式不起作用。对不起,如果问题是基本的。预先感谢您的回答。

module ser32to8(clk, dataIn, dataOut);
  input clk;
  input [32:0] dataIn;
  output [7:0] dataOut;

  always @(posedge clk) 
  begin
    dataOut <= dataIn << 8;
    end
    endmodule

问题背后的想法不太清楚,但我的猜测是你想在发送数据之前等待 4 个时钟周期,如果是这种情况,下面的代码片段可能会有所帮助,A counter to wait before 4时钟周期就可以了

module top (input         clk,rst,
            input  [31:0] dataIn,
            output [7:0]  dataOut
            ); 
reg    [31:0] tmp; 
reg    [31:0] inter; 
integer       count;

always @(posedge clk) 
begin 
  if (rst) begin
    count <= 0;
    tmp   <= '0;
  end
  else
  begin
    if (count < 3) begin
      tmp <= dataIn << 4;
      count <= count +1; end
    else if (count == 3) 
      begin
      inter <= tmp;
      count <= 0;
      end
    else
      begin
        tmp <= dataIn;
      end
    end
end

assign dataOut  = inter[7:0]; 
endmodule 

但是使用 tb 测试了一些限制 http://www.edaplayground.com/x/4Cg

Note: Please ignore the previous code it won't work(I was not clear so tried it differently)

编辑:

如果我正确理解你的问题,一个简单的方法是

一)

module top ( input         rst,clk,
             input  [31:0] dataIn,
             output [7:0]  dataOut);
reg [1:0] cnt;
always @(posedge clk) begin
  if (rst) cnt <= 'b0;
  else     cnt <= cnt + 1;
end

assign dataOut = (cnt == 0) ? dataIn [7:0]   :
                 (cnt == 1) ? dataIn [15:8]  :
                 (cnt == 2) ? dataIn [23:16] :
                 (cnt == 3) ? dataIn [31:24] :
                  '0;

endmodule

万一你不想单独写for循环会派上用场,让它更简单

b)

module top ( input             rst,clk,
             input      [31:0] dataIn,
             output reg [7:0]  dataOut);
reg [1:0] cnt;
integer i;
always @(posedge clk) begin
  if (rst) cnt <= 'b0;
  else     cnt <= cnt + 1;
end

always @ * begin
  for ( i =0;i < cnt ; i=i+1) begin 
    dataOut <= dataIn[(i*8)+:8]; end
end

endmodule

我已经尝试了两个测试用例并发现有效,tc's present @

a) http://www.edaplayground.com/x/VCF
b) http://www.edaplayground.com/x/4Cg

你可能想试一试

赋值失败的原因(除了你的代码没有做任何序列化)是因为你没有将 dataOut 声明为 reg,所以你不能在 [= =13=]块。

以下是您的正确做法。 (因为你没有说你想要序列化的顺序,我选择了最低字节在前,最高字节在后。要颠倒顺序,将 >> 换成 <<tmp[7:0] tmp[31:24].)

module ser32to8(
    input clk,
    input [31:0] dataIn,
    output [7:0] dataOut
);

// count: 0, 1, 2, 3, 0, ... (wraps automatically)
reg [1:0] count;
always @(posedge clk) begin
    count <= count + 2'd1;
end

reg [31:0] tmp;
always @(posedge clk) begin
    if (count == 2'd0)
        tmp <= dataIn;
    else
        tmp <= (tmp >> 8);
end

assign dataOut = tmp[7:0];

endmodule

你怎么能只取一部分dataIn数据呢?通过使用 [] 符号。 dataIn[7:0] 占用 8 个最低有效位,dataIn[15:8] 占用接下来的 8 位,依此类推直到 dataIn[31:24] 占用 8 个最高有效位。

要将此应用于您的问题,您可以这样做(考虑到这不是最佳解决方案,因为输出未注册,因此可能会出现故障)

module ser32to8(
    input wire clk,
    input wire [31:0] dataIn,
    output reg [7:0] dataOut
    );

    reg [1:0] cnt = 2'b00;
    always @(posedge clk)
      cnt <= cnt + 1;

    always @* begin
      case (cnt)
        2'd0: dataOut = dataIn[7:0];
        2'd1: dataOut = dataIn[15:8];
        2'd2: dataOut = dataIn[23:16];
        2'd3: dataOut = dataIn[31:24];
        default: dataOut = 8'h00;
      endcase
    end
endmodule

您必须将 dataOut 声明为 reg,因为您一直在使用它 block.Also,您正试图将 32 位 datain 分配给 8 位 dataout , 这在逻辑上是不正确的。

您可以按照下图设计您的电路。希望它对你有用。如果您需要代码,请随时与我联系。

SER 112 bits with 8 outputs in parallel