2024-10-22 20:31:51 +08:00
|
|
|
|
//RAM-BASED移位寄存器
|
|
|
|
|
|
|
|
|
|
module SHIFT_REGISTER #(
|
2024-11-03 20:38:29 +08:00
|
|
|
|
parameter reg [ 4:0] DATA_WIDTH = 16, // 输入/输出数据位宽
|
|
|
|
|
parameter IFOUTIMME = 1'b0 //此项为0时,直至RAM存满IMAGE_WIDTH后再输出valid,为1时立即输出valid,无论是否存满
|
|
|
|
|
)(
|
2024-10-22 20:31:51 +08:00
|
|
|
|
// 基本信号
|
|
|
|
|
input wire clk,
|
|
|
|
|
input wire reset,
|
|
|
|
|
// 数据线
|
|
|
|
|
input wire [DATA_WIDTH - 1:0] in_data,
|
2024-11-03 20:38:29 +08:00
|
|
|
|
input wire [7:0] in_user, //in_user[0]是hstart, 行开始标志位, 用于给SHIFT_REGISTER判断输出与输入data的addr距离
|
2024-10-22 20:31:51 +08:00
|
|
|
|
output wire [DATA_WIDTH - 1:0] out_data,
|
2024-11-03 20:38:29 +08:00
|
|
|
|
output wire [7:0] out_user,
|
2024-10-22 20:31:51 +08:00
|
|
|
|
// 有效信号
|
2024-11-03 20:38:29 +08:00
|
|
|
|
input wire in_valid, // 上一模块输出数据有效
|
|
|
|
|
output wire out_valid // 当前模块输出数据有效
|
2024-10-22 20:31:51 +08:00
|
|
|
|
);
|
|
|
|
|
|
2024-11-03 20:38:29 +08:00
|
|
|
|
reg [10:0] addr_a, addr_b;
|
|
|
|
|
wire cea, ceb;
|
|
|
|
|
reg fulldone;
|
2024-10-22 20:31:51 +08:00
|
|
|
|
|
2024-11-03 20:38:29 +08:00
|
|
|
|
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;
|
2024-10-22 20:31:51 +08:00
|
|
|
|
|
2024-11-03 20:38:29 +08:00
|
|
|
|
assign cea = in_valid;
|
|
|
|
|
assign ceb = in_valid_temp0;
|
|
|
|
|
assign out_valid = in_valid_temp1;
|
2024-10-22 20:31:51 +08:00
|
|
|
|
|
2024-11-03 20:38:29 +08:00
|
|
|
|
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);
|
2024-10-22 20:31:51 +08:00
|
|
|
|
end else begin
|
2024-11-03 20:38:29 +08:00
|
|
|
|
addr_b <= addr_b + 1;
|
|
|
|
|
wr_rd_distance_cnt <= wr_rd_distance_cnt + 1;
|
2024-10-22 20:31:51 +08:00
|
|
|
|
end
|
2024-11-03 20:38:29 +08:00
|
|
|
|
end else begin
|
|
|
|
|
addr_a <= addr_a;
|
|
|
|
|
addr_b <= addr_b;
|
|
|
|
|
wr_rd_distance_cnt <= wr_rd_distance_cnt;
|
2024-10-22 20:31:51 +08:00
|
|
|
|
end
|
2024-11-03 20:38:29 +08:00
|
|
|
|
end
|
2024-10-22 20:31:51 +08:00
|
|
|
|
|
2024-11-03 20:38:29 +08:00
|
|
|
|
always @(posedge clk) begin
|
|
|
|
|
if(reset) fulldone <= 0;
|
|
|
|
|
else if(cea && hstart && (addr_b != 0)) fulldone <= 1;
|
|
|
|
|
else fulldone <= fulldone;
|
|
|
|
|
end
|
2024-10-22 20:31:51 +08:00
|
|
|
|
|
2024-11-03 20:38:29 +08:00
|
|
|
|
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
|
2024-10-22 20:31:51 +08:00
|
|
|
|
|
2024-11-03 20:38:29 +08:00
|
|
|
|
.cea(cea), //input cea
|
|
|
|
|
.ceb(ceb), //input ceb
|
2024-10-22 20:31:51 +08:00
|
|
|
|
|
2024-11-03 20:38:29 +08:00
|
|
|
|
.ada(addr_a), //input [10:0] ada
|
|
|
|
|
.adb(addr_b), //input [10:0] adb
|
2024-10-22 20:31:51 +08:00
|
|
|
|
|
2024-11-03 20:38:29 +08:00
|
|
|
|
.din(din), //input [15:0] din
|
|
|
|
|
.dout(dout), //output [15:0] dout
|
2024-10-22 20:31:51 +08:00
|
|
|
|
|
2024-11-03 20:38:29 +08:00
|
|
|
|
.oce(1) //input oce
|
|
|
|
|
);
|
2024-10-22 20:31:51 +08:00
|
|
|
|
|
2024-11-03 20:38:29 +08:00
|
|
|
|
// 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
|
2024-10-22 20:31:51 +08:00
|
|
|
|
|