串行器 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
我正在尝试将序列化程序从 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