【问题标题】:Serializer 32 to 8 - Verilog HDL串行器 32 到 8 - Verilog HDL
【发布时间】:2017-10-03 00:58:18
【问题描述】:

我正在尝试将序列化器从 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 个时钟周期 32 位,你能解释一下吗?
  • @Emman 我将加载 32 位,然后我需要等待 4 个周期才能再次加载它们。在输出的同时,我将发送 4x8 位。
  • 我可以放置计数器,但我会在每 4 个时钟周期获得 32 位。向 ser32to8 提供数据的模块由 clk/4 计时。所以也许我不需要柜台。我只想移动 8 个空格并将它们放在输出端。

标签: verilog


【解决方案1】:

分配失败的原因(除了您的代码没有进行任何序列化)是因为您没有将dataOut 声明为reg,因此您不能在always 块内对其进行分配。

以下是正确操作的方法。 (因为你没有说你想要序列化的顺序,我选择了最低字节在前,最高字节在后。为了颠倒顺序,将&gt;&gt;&lt;&lt;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

【讨论】:

    【解决方案2】:

    你怎么能只把你的数据中的一部分取出来?通过使用 [] 表示法。 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
    

    【讨论】:

    • 如果dataIncnt &gt; 0时改变,输出无效。我认为从dataIn 采样是必要的,并且必须在cnt = 0 时应用。
    • 是的...我警告说这是一个次优的解决方案。此代码是作为示例提供的,说明如何使用子索引运算符仅获取变量的一部分,因为这是他最初的问题:“我怎样才能只获取我的 dataIn 的一部分?”
    【解决方案3】:

    您必须将 dataOut 声明为 reg,因为您在 always 块中使用它。此外,您尝试将 32 位 datain 分配给 8 位 dataout ,逻辑上不正确。

    【讨论】:

      【解决方案4】:

      问题背后的想法不是很清楚,但我的猜测是你想在发送数据之前等待 4 个时钟周期,如果是下面的情况 sn-p 可能会有所帮助,计数器在 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 测试有一些限制

      注意:请忽略前面的代码它不会工作(我不清楚所以 尝试不同)

      编辑:

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

      一)

      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 在场@

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

      你可以试试看

      【讨论】:

      • 我会测试它。我不想等待 4 个时钟周期来发送数据。我将在每 4 个 clk 上获得 32 位,并且我想在每个 clk 上发送 8 位。
      • tmp &lt;= dataIn 永远不会被执行,因为count 只会小于 3 或等于 3。不知道它应该做什么。
      • 并且该模块不会序列化任何内容,正如您在链接的测试台中看到的那样。
      【解决方案5】:

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

      SER 112 bits with 8 outputs in parallel

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-11-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多