ISP/rtl/BayerProcess/SHIFT_REGISTER.sv

103 lines
2.6 KiB
Systemverilog
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//RAM-BASED移位寄存器
module SHIFT_REGISTER #(
parameter reg [ 4:0] DATA_WIDTH = 16, // 输入/输出数据位宽
parameter IFOUTIMME = 1'b0 //此项为0时直至RAM存满IMAGE_WIDTH后再输出valid为1时立即输出valid无论是否存满
)(
// 基本信号
input wire clk,
input wire reset,
// 数据线
input wire [DATA_WIDTH - 1:0] in_data,
input wire [7:0] in_user, //in_user[0]是hstart, 行开始标志位, 用于给SHIFT_REGISTER判断输出与输入data的addr距离
output wire [DATA_WIDTH - 1:0] out_data,
output wire [7:0] out_user,
// 有效信号
input wire in_valid, // 上一模块输出数据有效
output wire out_valid // 当前模块输出数据有效
);
reg [10:0] addr_a, addr_b;
wire cea, ceb;
reg fulldone;
reg in_valid_temp0, in_valid_temp1;
always @(posedge clk) in_valid_temp0 <= in_valid && (fulldone || IFOUTIMME);
always @(posedge clk) in_valid_temp1 <= in_valid_temp0;
assign cea = in_valid;
assign ceb = in_valid_temp0;
assign out_valid = in_valid_temp1;
wire hstart;
assign hstart = in_user[0];
reg [15:0] wr_rd_distance_cnt;
always @(posedge clk) begin
if(reset) begin
addr_a <= ~0;
addr_b <= 0;
wr_rd_distance_cnt <= 0;
end else if(cea) begin
addr_a <= addr_a + 1;
if(hstart) begin
wr_rd_distance_cnt <= 0;
addr_b <= addr_a + 1 - (wr_rd_distance_cnt + 2);
end else begin
addr_b <= addr_b + 1;
wr_rd_distance_cnt <= wr_rd_distance_cnt + 1;
end
end else begin
addr_a <= addr_a;
addr_b <= addr_b;
wr_rd_distance_cnt <= wr_rd_distance_cnt;
end
end
always @(posedge clk) begin
if(reset) fulldone <= 0;
else if(cea && hstart && (addr_b != 0)) fulldone <= 1;
else fulldone <= fulldone;
end
wire [15:0] din, dout;
assign din = {{(16-DATA_WIDTH){1'b0}},in_data};
assign out_data = dout[DATA_WIDTH-1:0];
// Single-Double-Port-BRAM-IP Bypass Normal
Gowin_SDPB Gowin_SDPB_inst(
.clka(clk), //input clka
.clkb(clk), //input clkb
.reset(reset), //input reset
.cea(cea), //input cea
.ceb(ceb), //input ceb
.ada(addr_a), //input [10:0] ada
.adb(addr_b), //input [10:0] adb
.din(din), //input [15:0] din
.dout(dout), //output [15:0] dout
.oce(1) //input oce
);
// Single-Double-Port-BRAM-IP Bypass Normal
Gowin_SDPB_USER Gowin_SDPB_user_inst(
.clka(clk), //input clka
.clkb(clk), //input clkb
.reset(reset), //input reset
.cea(cea), //input cea
.ceb(ceb), //input ceb
.ada(addr_a), //input [10:0] ada
.adb(addr_b), //input [10:0] adb
.din(in_user), //input [7:0] din
.dout(out_user), //output [7:0] dout
.oce(1) //input oce
);
endmodule