반응형
wr_count_i가 DATA_WIDTH - 1 값에 도달하고 신호 ws_i가 LOW(0) 데이터 레지스터 data_reg_i에 오른쪽 채널 데이터(right_data_i) 할당
wr_count_i가 DATA_WIDTH - 1 값에 도달하고 신호 ws_i가 HIGH(1) 데이터 레지스터 data_reg_i에 왼쪽 채널 데이터(left_data_i)가 할당
위의 조건 중 어느 것도 충족되지 않으면 데이터 레지스터 'data_reg_i'는 오른쪽 시프트를 수행하여 최상위 비트(MSB)를 두 번째 최상위 비트로 이동하고 이전 MSB 값으로 최하위 비트(LSB)를 채웁니다.
SerialData.v
module SerialData#(
parameter DATA_WIDTH=16
) (
input i_sys_clk,
input i_sys_rst,
input [DATA_WIDTH-1:0] i_right_data,
input [DATA_WIDTH-1:0] i_left_data,
output reg [DATA_WIDTH-1:0] wr_count_o,
output reg ws_o,
output reg [DATA_WIDTH-1:0] data_reg_o
);
//Count the number of bits to be transmitted
//It has to be same as the data width
always @ (negedge i_sys_clk or posedge i_sys_rst) begin
if(i_sys_rst) begin
wr_count_o <= DATA_WIDTH[1'b0];
end else begin
if(wr_count_o == DATA_WIDTH - 1) begin
wr_count_o <= DATA_WIDTH[1'b0];
end else begin
wr_count_o <= wr_count_o + 1;
end
end
end
always @ (negedge i_sys_clk or posedge i_sys_rst) begin
if(i_sys_rst) begin
ws_o <= 1'b0;
end else begin
if(wr_count_o == DATA_WIDTH - 1) begin
ws_o <= ~ws_o;
end
end
end
//Data mux and shift register for left and right channels
//left valid data synchronization with o_WS
always @ (negedge i_sys_clk or posedge i_sys_rst) begin
if(i_sys_rst) begin
data_reg_o <= DATA_WIDTH[1'b0];
end else begin
if(wr_count_o == DATA_WIDTH - 1 && !ws_o) begin // left channel end
data_reg_o <= i_right_data;
end else if(wr_count_o == DATA_WIDTH - 1 && ws_o)begin // right channel end
data_reg_o <= i_left_data;
end else begin
data_reg_o <= {data_reg_o[DATA_WIDTH - 2:0], data_reg_o[DATA_WIDTH-1]};
end
end
end
endmodule
TB
`timescale 1ns/1ps
module SerialData_TB();
reg i_sys_clk;
reg i_sys_rst;
reg [15:0] i_right_data;
reg [15:0] i_left_data;
wire [15:0] wr_count_o;
wire ws_o;
wire [15:0] data_reg_o;
// Instantiate the SerialData module
SerialData #(
.DATA_WIDTH(16)
) my_serial_data (
.i_sys_clk(i_sys_clk),
.i_sys_rst(i_sys_rst),
.i_right_data(i_right_data),
.i_left_data(i_left_data),
.wr_count_o(wr_count_o),
.ws_o(ws_o),
.data_reg_o(data_reg_o)
);
// Clock generation
always begin
#5 i_sys_clk = ~i_sys_clk;
end
// Testbench stimulus
initial begin
i_sys_clk = 0;
i_sys_rst = 1;
i_right_data = 16'h0000;
i_left_data = 16'h0000;
// Reset the module
#10 i_sys_rst = 0;
// Observe the output for multiple clock cycles
#310;
// Change input data
i_right_data = 16'h1234;
i_left_data = 16'h5678;
// Observe the output for multiple clock cycles
#400;
// Finish the simulation
$finish;
end
endmodule
sim
반응형