Module PISO

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 3

module PISO_ShiftRegister #(

parameter DATA_WIDTH = 8
)(
input wire clk_rx,
input wire rst,
input wire valid_in,
input wire [DATA_WIDTH-1:0] Data_in,
output wire valid_out,
output wire [DATA_WIDTH-1:0] Data_out,
output reg ready_in,
output reg ready_out,
input wire clk_tx
);
// Internal register to store parallel input
reg [DATA_WIDTH-1:0] temp;

// Internal state
reg [DATA_WIDTH-1:0] shift_reg;

// Internal counter for serial output


reg [3:0] counter;

// Internal signals for handshaking


reg [DATA_WIDTH-1:0] next_data_out;
reg next_valid_out;
reg next_ready_in, next_ready_out;

// Synchronous process for parallel input


always_ff @(posedge clk_rx or posedge rst) begin
if (rst) begin
temp <= 0;
ready_in <= 1'b1;
end else if (valid_in && ready_in) begin
temp <= Data_in;
ready_in <= 1'b0;
end
end

// Synchronous process for serial output


always_ff @(posedge clk_tx or posedge rst) begin
if (rst) begin
shift_reg <= 0;
counter <= 4'b0;
valid_out <= 1'b0;
ready_out <= 1'b1;
end else if (counter == 4'b0) begin
// Drive data on positive edge
shift_reg <= {shift_reg[DATA_WIDTH-2:0], temp[DATA_WIDTH-1]};
counter <= 4'b1;
valid_out <= 1'b1;
next_ready_out <= 1'b0;
next_data_out <= shift_reg;
next_valid_out <= valid_out;
end else begin
// Drive data on negative edge
counter <= 4'b0;
valid_out <= next_valid_out;
ready_out <= next_ready_out;
next_ready_out <= 1'b1;
next_data_out <= shift_reg;
end
end

// Combinational logic for handshaking


always_comb begin
if (ready_out && valid_out)
next_ready_out = 1'b1;
else
next_ready_out = 1'b0;

if (ready_in && valid_in)


next_ready_in = 1'b1;
else
next_ready_in = 1'b0;
end

// Assign outputs
assign Data_out = next_data_out;
assign valid_out = next_valid_out;

Endmodule

module PISO_ShiftRegister_TB;
reg clk_rx, rst, clk_tx;
reg valid_in;
reg [7:0] Data_in;
wire valid_out;
wire [7:0] Data_out;
reg ready_in, ready_out;

// Instantiate the module


PISO_ShiftRegister #(
.DATA_WIDTH(8)
) dut (
.clk_rx(clk_rx),
.rst(rst),
.valid_in(valid_in),
.Data_in(Data_in),
.valid_out(valid_out),
.Data_out(Data_out),
.ready_in(ready_in),
.ready_out(ready_out),
.clk_tx(clk_tx)
);

// Clock generation
initial begin
clk_rx = 0;
rst = 1;
clk_tx = 0;
#5 rst = 0;
end
always #5 clk_rx = ~clk_rx;
always #2 clk_tx = ~clk_tx;

// Drive parallel input data through Data_in port in clk_rx speed


initial begin
valid_in = 0;
ready_in = 1;

#10 Data_in = 8'b11011010; // Example parallel input data


valid_in = 1;
#10 valid_in = 0;

#100 $finish;
end

// Receive the serial data from the design through Data_out port in clk_tx speed
initial begin
#20;
ready_out = 1;

// Monitor at receive and transmit interfaces


$monitor("Time=%0t || Data_in=%b, Valid_in=%b, Ready_in=%b || Data_out=%b, Valid_out=%b,
Ready_out=%b",
$time, Data_in, valid_in, ready_in, Data_out, valid_out, ready_out);
end
endmodule

You might also like