ODDR实现多bit单边沿采样数据转为多bit双沿采样数据
ODDR实现多bit单边沿采样数据转为多bit双沿采样数据
https://bbs.elecfans.com/m/jishu_2030303_1_1.html
module ddr_16to8_output_alt (
input wire clk,
input wire rst,
input wire [15:0] data_in,
input wire data_valid,
output wire [7:0] ddr_out,
output wire busy
);
// 内部信号
reg [3:0] bit_counter;
reg [15:0] data_reg;
reg busy_reg;
// 状态控制
always @(posedge clk) begin
if (rst) begin
bit_counter <= 4'b0;
busy_reg <= 1'b0;
data_reg <= 16'b0;
end else begin
if (data_valid && !busy_reg) begin
data_reg <= data_in;
bit_counter <= 4'b0;
busy_reg <= 1'b1;
end else if (busy_reg) begin
if (bit_counter == 4'd7) begin
busy_reg <= 1'b0;
end
bit_counter <= bit_counter + 1;
end
end
end
// 生成8个ODDR原语
genvar i;
generate
for (i = 0; i < 8; i = i + 1) begin : oddr_gen
// 为每个ODDR选择适当的数据位
wire rise_bit = data_reg[bit_counter * 2 + (i % 2 ? 0 : 1)];
wire fall_bit = data_reg[bit_counter * 2 + (i % 2 ? 1 : 0)];
ODDR #(
.DDR_CLK_EDGE("OPPOSITE_EDGE"),
.INIT(1'b0),
.SRTYPE("SYNC")
) ODDR_inst (
.Q(ddr_out[i]),
.C(clk),
.CE(1'b1),
.D1(rise_bit),
.D2(fall_bit),
.R(rst),
.S(1'b0)
);
end
endgenerate
assign busy = busy_reg;
endmodule