diff --git a/FIFO/SOFTFIFO.v b/FIFO/SOFTFIFO.v new file mode 100644 index 0000000..9c93736 --- /dev/null +++ b/FIFO/SOFTFIFO.v @@ -0,0 +1,894 @@ + +`timescale 1ns/1ps +// +// =========================================================================== +// Copyright (c) 2011-2022 Anlogic Inc. All Right Reserved. +// +// TEL: 86-21-61633787 +// WEB: http://www.anlogic.com/ +// =========================================================================== +// $Version : v1.1 +// $Date : 2022/07/08 +// $Description: asynchronous/synchronous FIFO rtl codes , fixed the error of +// gray code +// =========================================================================== +//`pragma protect begin +module SOFTFIFO #(parameter DATA_WIDTH_W = 16, + parameter DATA_WIDTH_R = 16, + parameter ADDR_WIDTH_W = 10, + parameter ADDR_WIDTH_R = 10, + parameter AL_FULL_NUM = 1021, + parameter AL_EMPTY_NUM = 2, + parameter SHOW_AHEAD_EN = 1'b1, + parameter OUTREG_EN = "OUTREG") ( + //SHOWAHEAD mode enable + //OUTREG, NOREG + //independent clock mode,fixed as asynchronous reset + input rst, //asynchronous port,active hight + input clkw, //write clock + input clkr, //read clock + input we, //write enable,active hight + input [(DATA_WIDTH_W - 1):0] di, //write data + input re, //read enable,active hight + output [(DATA_WIDTH_R - 1):0] dout, //read data + output reg valid, //read data valid flag + output reg full_flag, //fifo full flag + output empty_flag, //fifo empty flag + output reg afull, //fifo almost full flag + output aempty, //fifo almost empty flag + output [(ADDR_WIDTH_W - 1):0] wrusedw, //stored data number in fifo + output [(ADDR_WIDTH_R - 1):0] rdusedw //available data number for read + ) ; + //-------------------------------------------------------------------------------------------- + //-------------internal parameter and signals definition below--------------- + //-------------------------------------------------------------------------------------------- + //-------------parameter definition + localparam FULL_NUM = ({ADDR_WIDTH_W{1'b1}} - 1) ; + //-------------signals definition + reg asy_w_rst0 ; + reg asy_w_rst1 ; + reg asy_r_rst0 ; + reg asy_r_rst1 ; + wire rd_rst ; + wire wr_rst ; + wire [(ADDR_WIDTH_R - 1):0] rd_to_wr_addr ; // read address synchronized to write clock domain + wire [(ADDR_WIDTH_W - 1):0] wr_to_rd_addr ; // write address synchronized to read clock domain + reg [(ADDR_WIDTH_W - 1):0] wr_addr ; // current write address + reg [(ADDR_WIDTH_R - 1):0] rd_addr ; // current write address + wire wr_en_s ; + wire rd_en_s ; + reg [(ADDR_WIDTH_W - 1):0] shift_rdaddr ; + reg [(ADDR_WIDTH_R - 1):0] shift_wraddr ; + wire [(ADDR_WIDTH_W - 1):0] wr_addr_diff ; // the difference between read and write address(synchronized to write clock domain) + wire [(ADDR_WIDTH_R - 1):0] rd_addr_diff ; // the difference between read and write address(synchronized to read clock domain) + reg empty_flag_r1 ; + reg empty_flag_r2 ; + reg re_r1 ; + reg re_r2 ; + //-------------------------------------------------------------------------------------------- + //--------------------fuctional codes below--------------------------------- + //-------------------------------------------------------------------------------------------- + // ============================================= + // reset control logic below; + // ============================================= + //Asynchronous reset synchronous release on the write side + always + @(posedge clkw or + posedge rst) + begin + if (rst) + begin + asy_w_rst0 <= 1'b1 ; + asy_w_rst1 <= 1'b1 ; + end + else + begin + asy_w_rst0 <= 1'b0 ; + asy_w_rst1 <= asy_w_rst0 ; + end + end + //Asynchronous reset synchronous release on the read side + always + @(posedge clkr or + posedge rst) + begin + if (rst) + begin + asy_r_rst0 <= 1'b1 ; + asy_r_rst1 <= 1'b1 ; + end + else + begin + asy_r_rst0 <= 1'b0 ; + asy_r_rst1 <= asy_r_rst0 ; + end + end + assign rd_rst = asy_r_rst1 ; + assign wr_rst = asy_w_rst1 ; + // ============================================= + // address generate logic below; + // ============================================= + // write and read ram enable + assign wr_en_s = ((!full_flag) & we) ; + assign rd_en_s = ((!empty_flag) & re) ; + // generate write fifo address + always + @(posedge clkw or + posedge wr_rst) + begin + if ((wr_rst == 1'b1)) + wr_addr <= 'b0 ; + else + if (wr_en_s) + wr_addr <= (wr_addr + 1) ; + end + // generate rd fifo address + always + @(posedge clkr or + posedge rd_rst) + begin + if ((rd_rst == 1'b1)) + rd_addr <= 'b0 ; + else + if (rd_en_s) + rd_addr <= (rd_addr + 1) ; + end + always + @(*) + begin + if ((ADDR_WIDTH_R >= ADDR_WIDTH_W)) + begin + shift_rdaddr = (rd_to_wr_addr >> (ADDR_WIDTH_R - ADDR_WIDTH_W)) ; + shift_wraddr = (wr_to_rd_addr << (ADDR_WIDTH_R - ADDR_WIDTH_W)) ; + end + else + begin + shift_rdaddr = (rd_to_wr_addr << (ADDR_WIDTH_W - ADDR_WIDTH_R)) ; + shift_wraddr = (wr_to_rd_addr >> (ADDR_WIDTH_W - ADDR_WIDTH_R)) ; + end + end + // two's complement format + assign wr_addr_diff = (wr_addr - shift_rdaddr) ; // the count of data writen to fifo + assign rd_addr_diff = (shift_wraddr - rd_addr) ; // the count of data available for read + // ============================================= + // generate all output flag and count below; + // ============================================= + // generate fifo full_flag indicator + always + @(posedge clkw or + posedge wr_rst) + begin + if ((wr_rst == 1'b1)) + full_flag <= 1'b0 ; + else + if ((wr_addr_diff >= FULL_NUM)) + full_flag <= 1'b1 ; + else + full_flag <= 1'b0 ; + end + // generate fifo afull indicator + always + @(posedge clkw or + posedge wr_rst) + begin + if ((wr_rst == 1'b1)) + afull <= 1'b0 ; + else + if ((wr_addr_diff >= AL_FULL_NUM)) + afull <= 1'b1 ; + else + afull <= 1'b0 ; + end + // generate fifo empty_flag indicator + /* verilator lint_off WIDTHEXPAND */ + assign empty_flag = ((rd_addr_diff == 5'b0) ? 1'b1 : 1'b0) ; + // generate fifo aempty indicator + assign aempty = ((rd_addr_diff <= AL_EMPTY_NUM) ? 1'b1 : 1'b0) ; + // the count of data writen to fifo + assign wrusedw = wr_addr_diff ; + // the count of data available for read + assign rdusedw = rd_addr_diff ; + // delay empty_flag for 2cycle + always + @(posedge clkr or + posedge rd_rst) + begin + if ((rd_rst == 1'b1)) + begin + empty_flag_r1 <= 1'b1 ; + empty_flag_r2 <= 1'b1 ; + end + else + begin + empty_flag_r1 <= empty_flag ; + empty_flag_r2 <= empty_flag_r1 ; + end + end + // delay rd_en_s for 2cycle + always + @(posedge clkr or + posedge rd_rst) + begin + if ((rd_rst == 1'b1)) + begin + re_r1 <= 1'b0 ; + re_r2 <= 1'b0 ; + end + else + begin + re_r1 <= rd_en_s ; + re_r2 <= re_r1 ; + end + end + // generate data output valid flag + always + @(*) + begin + if ((SHOW_AHEAD_EN && (OUTREG_EN == "NOREG"))) + valid = (!empty_flag) ; + else + if (((!SHOW_AHEAD_EN) && (OUTREG_EN == "OUTREG"))) + valid = (re_r2 & (!empty_flag_r2)) ; + else + valid = (re_r1 & (!empty_flag_r1)) ; + end + // ============================================= + // instance logic below; + // ============================================= + // fifo read address synchronous to write clock domain using gray code + fifo_cross_domain_addr_process_al_SOFTFIFO #(.ADDR_WIDTH(ADDR_WIDTH_R)) rd_to_wr_cross_inst (.primary_asreset_i(rd_rst), + .secondary_asreset_i(wr_rst), + .primary_clk_i(clkr), + .secondary_clk_i(clkw), + .primary_addr_i(rd_addr), + .secondary_addr_o(rd_to_wr_addr)) ; + // fifo write address synchronous to read clock domain using gray code + fifo_cross_domain_addr_process_al_SOFTFIFO #(.ADDR_WIDTH(ADDR_WIDTH_W)) wr_to_rd_cross_inst (.primary_asreset_i(wr_rst), + .secondary_asreset_i(rd_rst), + .primary_clk_i(clkw), + .secondary_clk_i(clkr), + .primary_addr_i(wr_addr), + .secondary_addr_o(wr_to_rd_addr)) ; + ram_infer_SOFTFIFO #( + .DATAWIDTH_A(DATA_WIDTH_W), + .ADDRWIDTH_A(ADDR_WIDTH_W), + .DATAWIDTH_B(DATA_WIDTH_R), + .ADDRWIDTH_B(ADDR_WIDTH_R), + .MODE("SDP"), + .REGMODE_B(OUTREG_EN) + /* verilator lint_off PINMISSING */ + ) ram_inst ( + .clka(clkw), + .rsta(wr_rst), + .cea(1'b1), + .wea(wr_en_s), + .ocea(1'b0), + .dia(di), + .addra(wr_addr), + .clkb(clkr), + .rstb(rd_rst), + .ceb((SHOW_AHEAD_EN | rd_en_s)), + .web(1'b0), + .oceb(1'b1), + /* verilator lint_off WIDTHEXPAND */ + .addrb((rd_addr + (SHOW_AHEAD_EN & rd_en_s))), + .dob(dout) + ); +endmodule + + + +`timescale 1ns/1ps +// =========================================================================== +// $Version : v1.0 +// $Date : 2022/04/26 +// $Description: fifo write and read address crocess domain process +// =========================================================================== +/* verilator lint_off DECLFILENAME */ +module fifo_cross_domain_addr_process_al_SOFTFIFO #(parameter ADDR_WIDTH = 9) ( + input primary_asreset_i, + input secondary_asreset_i, + input primary_clk_i, + input secondary_clk_i, + input [(ADDR_WIDTH - 1):0] primary_addr_i, + output reg [(ADDR_WIDTH - 1):0] secondary_addr_o) ; + //-------------------------------------------------------------------------------------------- + //-------------internal parameter and signals definition below--------------- + //-------------------------------------------------------------------------------------------- + //-------------localparam definition + //-------------signals definition + wire [(ADDR_WIDTH - 1):0] primary_addr_gray ; + reg [(ADDR_WIDTH - 1):0] primary_addr_gray_reg ; /* fehdl keep="true" */ + reg [(ADDR_WIDTH - 1):0] sync_r1 ; /* fehdl keep="true" */ + reg [(ADDR_WIDTH - 1):0] primary_addr_gray_sync ; + //-------------------------------------------------------------------------------------------- + //--------------------fuctional codes below--------------------------------- + //-------------------------------------------------------------------------------------------- + function [(ADDR_WIDTH - 1):0] gray2bin ; + input [(ADDR_WIDTH - 1):0] gray ; + integer j ; + begin + gray2bin[(ADDR_WIDTH - 1)] = gray[(ADDR_WIDTH - 1)] ; + for (j = (ADDR_WIDTH - 1) ; (j > 0) ; j = (j - 1)) + gray2bin[(j - 1)] = (gray2bin[j] ^ gray[(j - 1)]) ; + end + endfunction + function [(ADDR_WIDTH - 1):0] bin2gray ; + input [(ADDR_WIDTH - 1):0] bin ; + integer j ; + begin + bin2gray[(ADDR_WIDTH - 1)] = bin[(ADDR_WIDTH - 1)] ; + for (j = (ADDR_WIDTH - 1) ; (j > 0) ; j = (j - 1)) + bin2gray[(j - 1)] = (bin[j] ^ bin[(j - 1)]) ; + end + endfunction + // convert primary address to grey code + assign primary_addr_gray = bin2gray(primary_addr_i) ; + // register the primary Address Pointer gray code + always + @(posedge primary_clk_i or + posedge primary_asreset_i) + begin + if ((primary_asreset_i == 1'b1)) + primary_addr_gray_reg <= 0 ; + else + primary_addr_gray_reg <= primary_addr_gray ; + end + //-------------------------------------------------------------------- + // secondary clock Domain + //-------------------------------------------------------------------- + // synchronize primary address grey code onto the secondary clock + always + @(posedge secondary_clk_i or + posedge secondary_asreset_i) + begin + if ((secondary_asreset_i == 1'b1)) + begin + sync_r1 <= 0 ; + primary_addr_gray_sync <= 0 ; + end + else + begin + sync_r1 <= primary_addr_gray_reg ; + primary_addr_gray_sync <= sync_r1 ; + end + end + // convert the synchronized primary address grey code back to binary + always + @(posedge secondary_clk_i or + posedge secondary_asreset_i) + begin + if ((secondary_asreset_i == 1'b1)) + secondary_addr_o <= 0 ; + else + secondary_addr_o <= gray2bin(primary_addr_gray_sync) ; + end +endmodule + + + +`timescale 1ns/1ps +// =========================================================================== +// $Version : v1.0 +// $Date : 2022/04/26 +// $Description: DRAM/ERAM infer logic +// =========================================================================== +module ram_infer_SOFTFIFO (clka, + rsta, + cea, + ocea, + wea, + dia, + addra, + doa, + clkb, + rstb, + ceb, + oceb, + web, + dib, + addrb, + dob) ; + //parameter + parameter MODE = "SDP" ; //SP, SDP, DP + parameter BYTE_SIZE = 8 ; //8, 9, 10 + /* verilator lint_off UNUSEDPARAM */ + parameter INIT_FILE = "" ; //memory initialization file which can be $readmemh, generated by software from .mif + /* verilator lint_off UNUSEDPARAM */ + parameter INIT_VALUE = 0 ; + parameter USE_BYTE_WEA = 0 ; //0,1, use Byte Writes or not + parameter DATAWIDTH_A = 32 ; //A WIDTH + parameter WEA_WIDTH = ((USE_BYTE_WEA == 0) ? 1 : (DATAWIDTH_A / BYTE_SIZE)) ; //wea port width + parameter REGMODE_A = "NOREG" ; //OUTREG, NOREG + parameter RESETMODE_A = "ASYNC" ; //SYNC, ASYNC, ARSR + parameter INITVAL_A = {DATAWIDTH_A{1'b0}} ; //A initial value or reset value + parameter WRITEMODE_A = "NORMAL" ; //NORMAL, WRITETHROUGH, READBEFOREWRITE + parameter ADDRWIDTH_A = 5 ; //A ADDR WIDTH + parameter DATADEPTH_A = (2 ** ADDRWIDTH_A) ; //A DEPTH + parameter SSROVERCE_A = "ENABLE" ; //ENABLE, DISABLE + parameter USE_BYTE_WEB = USE_BYTE_WEA ; //0,1, use Byte Writes or not + parameter DATAWIDTH_B = DATAWIDTH_A ; //B WIDTH + parameter WEB_WIDTH = ((USE_BYTE_WEB == 0) ? 1 : (DATAWIDTH_B / BYTE_SIZE)) ; //web port width + parameter REGMODE_B = "NOREG" ; //OUTREG, NOREG + parameter RESETMODE_B = "ASYNC" ; //SYNC, ASYNC, ARSR + parameter INITVAL_B = {DATAWIDTH_B{1'b0}} ; //B initial value or reset value + parameter WRITEMODE_B = "NORMAL" ; //NORMAL, WRITETHROUGH, READBEFOREWRITE + parameter ADDRWIDTH_B = ADDRWIDTH_A ; //B ADDR WIDTH + parameter DATADEPTH_B = (2 ** ADDRWIDTH_B) ; //A DEPTH + parameter SSROVERCE_B = "ENABLE" ; //ENABLE, DISABLEi + //input + input clka, + rsta, + cea, + ocea ; + input [(WEA_WIDTH - 1):0] wea ; + input [(DATAWIDTH_A - 1):0] dia ; + input [(ADDRWIDTH_A - 1):0] addra ; + input clkb, + rstb, + ceb, + oceb ; + input [(WEB_WIDTH - 1):0] web ; + input [(DATAWIDTH_B - 1):0] dib ; + input [(ADDRWIDTH_B - 1):0] addrb ; + //output + output [(DATAWIDTH_A - 1):0] doa ; + output [(DATAWIDTH_B - 1):0] dob ; + // check parameters + //integer fp; + localparam MIN_WIDTH = ((DATAWIDTH_A > DATAWIDTH_B) ? DATAWIDTH_B : DATAWIDTH_A) ; + localparam MAX_DEPTH = ((DATADEPTH_A > DATADEPTH_B) ? DATADEPTH_A : DATADEPTH_B) ; + localparam WIDTHRATIO_A = (DATAWIDTH_A / MIN_WIDTH) ; + localparam WIDTHRATIO_B = (DATAWIDTH_B / MIN_WIDTH) ; + reg [(MIN_WIDTH - 1):0] memory [(MAX_DEPTH - 1):0] ; /* fehdl force_ram=1, ram_style="bram" */ + reg [(DATAWIDTH_A - 1):0] doa_tmp = INITVAL_A ; + reg [(DATAWIDTH_B - 1):0] dob_tmp = INITVAL_B ; + reg [(DATAWIDTH_A - 1):0] doa_tmp2 = INITVAL_A ; + reg [(DATAWIDTH_B - 1):0] dob_tmp2 = INITVAL_B ; + /* verilator lint_off UNUSEDSIGNAL */ + integer i ; + //Initial value + // if (INIT_FILE != "") begin + // initial $readmemb(INIT_FILE, memory); + // end else begin + // initial begin + // for(i=0; i> 1) ^ rbinnext; - assign rgraynextm1 = ((rbinnext + 1'b1) >> 1) ^ (rbinnext + 1'b1); - - //--------------------------------------------------------------- - // FIFO empty when the next rptr == synchronized wptr or on reset - //--------------------------------------------------------------- - assign rempty_val = (rgraynext == rq2_wptr); - assign arempty_val = (rgraynextm1 == rq2_wptr); - - always @ (posedge rclk or negedge rrst_n) begin - - if (!rrst_n) begin - arempty <= 1'b0; - rempty <= 1'b1; - end - else begin - arempty <= arempty_val; - rempty <= rempty_val; - end - - end - -endmodule - -`resetall diff --git a/FIFO/sync_ptr.v b/FIFO/sync_ptr.v deleted file mode 100644 index 416bbb8..0000000 --- a/FIFO/sync_ptr.v +++ /dev/null @@ -1,30 +0,0 @@ -// distributed under the mit license -// https://opensource.org/licenses/mit-license.php - -`timescale 1 ns / 1 ps -`default_nettype none - -module sync_ptr - - #( - parameter ASIZE = 4 - )( - input wire dest_clk, - input wire dest_rst_n, - input wire [ASIZE:0] src_ptr, - output reg [ASIZE:0] dest_ptr - ); - - reg [ASIZE:0] ptr_x; - - always @(posedge dest_clk or negedge dest_rst_n) begin - - if (!dest_rst_n) - {dest_ptr,ptr_x} <= 0; - else - {dest_ptr,ptr_x} <= {ptr_x,src_ptr}; - end - -endmodule - -`resetall diff --git a/FIFO/sync_r2w.v b/FIFO/sync_r2w.v deleted file mode 100644 index 05d65fe..0000000 --- a/FIFO/sync_r2w.v +++ /dev/null @@ -1,31 +0,0 @@ -// distributed under the mit license -// https://opensource.org/licenses/mit-license.php - -`timescale 1 ns / 1 ps -`default_nettype none - -module sync_r2w - - #( - parameter ASIZE = 4 - )( - input wire wclk, - input wire wrst_n, - input wire [ASIZE:0] rptr, - output reg [ASIZE:0] wq2_rptr - ); - - reg [ASIZE:0] wq1_rptr; - - always @(posedge wclk or negedge wrst_n) begin - - if (!wrst_n) - {wq2_rptr,wq1_rptr} <= 0; - else - {wq2_rptr,wq1_rptr} <= {wq1_rptr,rptr}; - - end - -endmodule - -`resetall diff --git a/FIFO/sync_w2r.v b/FIFO/sync_w2r.v deleted file mode 100644 index 396250b..0000000 --- a/FIFO/sync_w2r.v +++ /dev/null @@ -1,31 +0,0 @@ -// distributed under the mit license -// https://opensource.org/licenses/mit-license.php - -`timescale 1 ns / 1 ps -`default_nettype none - -module sync_w2r - - #( - parameter ASIZE = 4 - )( - input wire rclk, - input wire rrst_n, - output reg [ASIZE:0] rq2_wptr, - input wire [ASIZE:0] wptr - ); - - reg [ASIZE:0] rq1_wptr; - - always @(posedge rclk or negedge rrst_n) begin - - if (!rrst_n) - {rq2_wptr,rq1_wptr} <= 0; - else - {rq2_wptr,rq1_wptr} <= {rq1_wptr,wptr}; - - end - -endmodule - -`resetall diff --git a/FIFO/wptr_full.v b/FIFO/wptr_full.v deleted file mode 100644 index f067d6b..0000000 --- a/FIFO/wptr_full.v +++ /dev/null @@ -1,65 +0,0 @@ -// distributed under the mit license -// https://opensource.org/licenses/mit-license.php - -`timescale 1 ns / 1 ps -`default_nettype none - -module wptr_full - - #( - parameter ADDRSIZE = 4 - )( - input wire wclk, - input wire wrst_n, - input wire winc, - input wire [ADDRSIZE :0] wq2_rptr, - output reg wfull, - output reg awfull, - output wire [ADDRSIZE-1:0] waddr, - output reg [ADDRSIZE :0] wptr - ); - - reg [ADDRSIZE:0] wbin; - wire [ADDRSIZE:0] wgraynext, wbinnext, wgraynextp1; - wire awfull_val, wfull_val; - - // GRAYSTYLE2 pointer - always @(posedge wclk or negedge wrst_n) begin - - if (!wrst_n) - {wbin, wptr} <= 0; - else - {wbin, wptr} <= {wbinnext, wgraynext}; - - end - - // Memory write-address pointer (okay to use binary to address memory) - assign waddr = wbin[ADDRSIZE-1:0]; - assign wbinnext = wbin + {{(ADDRSIZE - 1){1'b0}}, (winc & ~wfull) }; - assign wgraynext = (wbinnext >> 1) ^ wbinnext; - assign wgraynextp1 = ((wbinnext + 1'b1) >> 1) ^ (wbinnext + 1'b1); - - //------------------------------------------------------------------ - // Simplified version of the three necessary full-tests: - // assign wfull_val=((wgnext[ADDRSIZE] !=wq2_rptr[ADDRSIZE] ) && - // (wgnext[ADDRSIZE-1] !=wq2_rptr[ADDRSIZE-1]) && - // (wgnext[ADDRSIZE-2:0]==wq2_rptr[ADDRSIZE-2:0])); - //------------------------------------------------------------------ - - assign wfull_val = (wgraynext == {~wq2_rptr[ADDRSIZE:ADDRSIZE-1],wq2_rptr[ADDRSIZE-2:0]}); - assign awfull_val = (wgraynextp1 == {~wq2_rptr[ADDRSIZE:ADDRSIZE-1],wq2_rptr[ADDRSIZE-2:0]}); - - always @(posedge wclk or negedge wrst_n) begin - - if (!wrst_n) begin - awfull <= 1'b0; - wfull <= 1'b0; - end else begin - awfull <= awfull_val; - wfull <= wfull_val; - end - end - -endmodule - -`resetall diff --git a/Merge/chanels_to_RGB.v b/Merge/chanels_to_RGB.v index 335daf1..e9a45ad 100644 --- a/Merge/chanels_to_RGB.v +++ b/Merge/chanels_to_RGB.v @@ -12,15 +12,34 @@ module chanels_to_RGB #( input [15:0] data_in [2:0], // 0:R 1:G 2:B // 输出相关 - input data_que, // 数据请求 + input out_que, // 数据请求 output out_en, output [3 * OUT_DEPTH - 1:0] data_out ); + localparam READ_DATA = 0; + localparam SEND_DATA = 1; + + reg [1:0] state, nextState; reg [31:0] data_cal [2:0]; // 用于保存运算结果,防止溢出 reg fifo_en; reg [3 * OUT_DEPTH - 1:0] fifo_in; // 输入fifo中缓存 - wire fifo_empty; - // wire fifo_alempty; + wire fifo_empty, fifo_que; + + always @(posedge clk or posedge reset) begin + if (reset) begin + state <= READ_DATA; + end + else begin + state <= nextState; + end + end + + always @(*) begin + case (state) + READ_DATA: nextState = (in_en) ? SEND_DATA : READ_DATA; + SEND_DATA: nextState = READ_DATA; + endcase + end always @(posedge clk or posedge reset) begin if (reset) begin @@ -32,43 +51,52 @@ module chanels_to_RGB #( fifo_in <= 0; end else begin - if (in_en) begin - data_cal[0] <= data_in[0] * OUT_DEPTH / IN_DEPTH; - data_cal[1] <= data_in[1] * OUT_DEPTH / IN_DEPTH; - data_cal[2] <= data_in[2] * OUT_DEPTH / IN_DEPTH; + case (state) + READ_DATA: begin + fifo_en <= 0; + + if (in_en) begin + data_cal[0] <= data_in[0] * OUT_DEPTH / IN_DEPTH; + data_cal[1] <= data_in[1] * OUT_DEPTH / IN_DEPTH; + data_cal[2] <= data_in[2] * OUT_DEPTH / IN_DEPTH; - fifo_in <= {data_cal[0][OUT_DEPTH - 1:0], data_cal[1][OUT_DEPTH - 1:0],data_cal[2][OUT_DEPTH - 1:0]}; - // data_out <= {data_cal[0][OUT_DEPTH - 1:0], data_cal[1][OUT_DEPTH - 1:0],data_cal[2][OUT_DEPTH - 1:0]}; - end - fifo_en <= in_en; + end + end + + SEND_DATA: begin + fifo_en <= 1; + fifo_in <= {data_cal[0][OUT_DEPTH - 1:0], data_cal[1][OUT_DEPTH - 1:0],data_cal[2][OUT_DEPTH - 1:0]}; + end + endcase end end // 存在数据请求且FIFO不为空时,才发送数据 - assign out_en = (data_que && !fifo_empty) ? 1 : 0; + assign fifo_que = (out_que && !fifo_empty) ? 1 : 0; - async_fifo #( - .DSIZE(3 * OUT_DEPTH), - .ASIZE(4), - .FALLTHROUGH("False") + SOFTFIFO #( + .DATA_WIDTH_W(3 * OUT_DEPTH), + .DATA_WIDTH_R(3 * OUT_DEPTH) ) RGB_FIFO ( - .wclk(clk), - .rclk(clk), - .wrst_n(reset), - .rrst_n(reset), - - .winc(fifo_en), - .wdata(fifo_in), - /* verilator lint_off PINCONNECTEMPTY */ - .wfull(), - /* verilator lint_off PINCONNECTEMPTY */ - .awfull(), - - /* verilator lint_off PINCONNECTEMPTY */ - .arempty(), - .rempty(fifo_empty), - .rdata(data_out), - .rinc(out_en) + .rst(reset), //asynchronous port,active hight + .clkw(clk), //write clock + .clkr(clk), //read clock + .we(fifo_en), //write enable,active hight + .di(fifo_in), //write data + .re(fifo_que), //read enable,active hight + .dout(data_out), //read data + .valid(out_en), //read data valid flag + /* verilator lint_off PINCONNECTEMPTY */ + .full_flag(), //fifo full flag + .empty_flag(fifo_empty), //fifo empty flag + /* verilator lint_off PINCONNECTEMPTY */ + .afull(), //fifo almost full flag + /* verilator lint_off PINCONNECTEMPTY */ + .aempty(), //fifo almost empty flag + /* verilator lint_off PINCONNECTEMPTY */ + .wrusedw(), //stored data number in fifo + /* verilator lint_off PINCONNECTEMPTY */ + .rdusedw() //available data number for read ); endmodule diff --git a/isp.v b/isp.v index 41f87a2..15d2487 100644 --- a/isp.v +++ b/isp.v @@ -60,7 +60,7 @@ module isp #( .in_en(rgb_en), .data_in({im_red, im_green, im_blue}), - .data_que(scale_in_que), + .out_que(scale_in_que), .out_en(scale_in_en), .data_out(scale_in_data) ); diff --git a/sim/sc_main.cpp b/sim/sc_main.cpp index 9174ad6..334d272 100644 --- a/sim/sc_main.cpp +++ b/sim/sc_main.cpp @@ -65,6 +65,9 @@ SC_MODULE (TB_ISP) { data_out[1].write(image[( pos_y + 1 ) * IM_WIDTH + pos_x]); data_out[2].write(image[( pos_y + 2 ) * IM_WIDTH + pos_x]); + wait(1); + data_en.write(0); + if (pos_x++ >= IM_WIDTH) { pos_x = 0; pos_y++; @@ -101,7 +104,7 @@ int sc_main(int argc, char* argv[]) { // Open image ifstream in_image; ofstream out_image; - in_image.open("./Demosaic/sim/transform/test.bin", ios::in | ios::binary); + in_image.open("../Demosaic/sim/transform/test.bin", ios::in | ios::binary); out_image.open("./out.bin", ios::out | ios::binary); if (!in_image.is_open()) { cout << "Open image fail" << endl; @@ -113,6 +116,7 @@ int sc_main(int argc, char* argv[]) { // Read image // uint8_t buf[IM_SIZE * 2] = {0}; auto buf = make_unique(2 * IM_SIZE); + // vector> buf(IM_HEIGHT, vector(IM_WIDTH, 0)); in_image.read((char*)buf.get(), IM_SIZE * 2); in_image.close(); // Reshape data