模块很小,就是将一个八位输入按照顺序依次串行输出。最终波形如下图展示:
模块设计
module parallelserial( input logic clk, input logic rstn, input logic [7:0] data_in, input logic din_valid, output logic dout_valid, output logic data_out, output logic busy ); logic [7:0] shift_reg; logic [2:0] bit_counter; logic last_bit; always_ff @(posedge clk or negedge rstn) begin if (!rstn) begin shift_reg <= 8'b0; bit_counter <= 3'b0; dout_valid <= 1'b0; data_out <= 1'b0; busy <= 1'b0; last_bit <= 1'b0; end else begin if (din_valid && !busy) begin shift_reg <= data_in; bit_counter <= 3'b0; busy <= 1'b1; dout_valid <= 1'b0; last_bit <= 1'b0; end else if (busy) begin data_out <= shift_reg[0]; // LSB first shift_reg <= shift_reg >> 1; // Right shift if (bit_counter == 3'd7) begin last_bit <= 1'b1; end else begin bit_counter <= bit_counter + 1; end if (last_bit) begin busy <= 1'b0; dout_valid <= 1'b1; last_bit <= 1'b0; end else begin dout_valid <= 1'b0; end end else begin dout_valid <= 1'b0; end end end endmodule
测试模块
`timescale 1ns/1ps module tb_parallelserial; // 信号声明 logic clk; logic rstn; logic [7:0] data_in; logic din_valid; logic dout_valid; logic data_out; // 实例化被测模块 parallelserial uut ( .clk(clk), .rstn(rstn), .data_in(data_in), .din_valid(din_valid), .dout_valid(dout_valid), .data_out(data_out) ); // 时钟生成 initial begin clk = 0; forever #5 clk = ~clk; // 10ns 时钟周期 end // 测试过程 initial begin // 初始化信号 rstn = 0; data_in = 8'b0; din_valid = 0; // 释放复位 #15; rstn = 1; // 发送数据 #10; data_in = 8'b10101111; din_valid = 1; #10; din_valid = 0; // 等待数据输出完成 wait (dout_valid); #10; end // 监视信号变化 initial begin $monitor("Time: %0t | data_in: %b | din_valid: %b | data_out: %b | dout_valid: %b", $time, data_in, din_valid, data_out, dout_valid); end // 波形记录 initial begin $dumpfile("waveform.vcd"); // 指定波形文件名 $dumpvars(0, tb_parallelserial); // 记录所有变量 end endmodule