change fifo source and finish testbench file for isp
This commit is contained in:
parent
21c763f54f
commit
74425d1c28
|
@ -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<MAX_DEPTH; i=i+1) begin
|
||||||
|
// memory[i] <= INIT_VALUE;
|
||||||
|
// end
|
||||||
|
// end
|
||||||
|
// end
|
||||||
|
//write data
|
||||||
|
always
|
||||||
|
@(posedge clka)
|
||||||
|
begin
|
||||||
|
if (cea)
|
||||||
|
begin
|
||||||
|
write_a (addra,
|
||||||
|
dia,
|
||||||
|
wea) ;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
always
|
||||||
|
@(posedge clkb)
|
||||||
|
begin
|
||||||
|
if (ceb)
|
||||||
|
begin
|
||||||
|
if ((MODE == "DP"))
|
||||||
|
begin
|
||||||
|
write_b (addrb,
|
||||||
|
dib,
|
||||||
|
web) ;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
reg rsta_p1 = 1,
|
||||||
|
rsta_p2 = 1 ;
|
||||||
|
wire rsta_p3 = ((rsta_p2 | rsta_p1) | rsta) ;
|
||||||
|
always
|
||||||
|
@(posedge clka or
|
||||||
|
posedge rsta)
|
||||||
|
begin
|
||||||
|
if (rsta)
|
||||||
|
begin
|
||||||
|
rsta_p1 <= 1 ;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
rsta_p1 <= 0 ;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
always
|
||||||
|
@(negedge clka)
|
||||||
|
begin
|
||||||
|
rsta_p2 <= rsta_p1 ;
|
||||||
|
end
|
||||||
|
//read data
|
||||||
|
wire sync_rsta = ((RESETMODE_A == "SYNC") && rsta) ;
|
||||||
|
wire async_rsta = ((RESETMODE_A == "ASYNC") ? rsta : ((RESETMODE_A == "ARSR") ? rsta_p3 : 0)) ;
|
||||||
|
wire ssroverce_a = ((SSROVERCE_A == "ENABLE") && sync_rsta) ;
|
||||||
|
/* verilator lint_off WIDTHEXPAND */
|
||||||
|
wire ceoverssr_a = ((SSROVERCE_A == "DISABLE") && sync_rsta) ;
|
||||||
|
always
|
||||||
|
@(posedge clka or
|
||||||
|
posedge async_rsta)
|
||||||
|
begin
|
||||||
|
if (async_rsta)
|
||||||
|
begin
|
||||||
|
doa_tmp2 <= INITVAL_A ;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if (ssroverce_a)
|
||||||
|
begin
|
||||||
|
doa_tmp2 <= INITVAL_A ;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if (ocea)
|
||||||
|
begin
|
||||||
|
if (ceoverssr_a)
|
||||||
|
begin
|
||||||
|
doa_tmp2 <= INITVAL_A ;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
doa_tmp2 <= doa_tmp ;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
always
|
||||||
|
@(posedge clka or
|
||||||
|
posedge async_rsta)
|
||||||
|
begin
|
||||||
|
if (async_rsta)
|
||||||
|
begin
|
||||||
|
doa_tmp <= INITVAL_A ;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if (sync_rsta)
|
||||||
|
begin
|
||||||
|
doa_tmp <= INITVAL_A ;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
if (cea)
|
||||||
|
begin
|
||||||
|
if (((MODE == "SP") || (MODE == "DP")))
|
||||||
|
begin
|
||||||
|
read_a (addra,
|
||||||
|
dia,
|
||||||
|
wea) ;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
reg rstb_p1 = 1,
|
||||||
|
rstb_p2 = 1 ;
|
||||||
|
wire rstb_p3 = ((rstb_p1 | rstb_p2) | rstb) ;
|
||||||
|
always
|
||||||
|
@(posedge clkb or
|
||||||
|
posedge rstb)
|
||||||
|
begin
|
||||||
|
if (rstb)
|
||||||
|
begin
|
||||||
|
rstb_p1 <= 1 ;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
rstb_p1 <= 0 ;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
always
|
||||||
|
@(negedge clkb)
|
||||||
|
begin
|
||||||
|
rstb_p2 <= rstb_p1 ;
|
||||||
|
end
|
||||||
|
wire sync_rstb = ((RESETMODE_B == "SYNC") && rstb) ;
|
||||||
|
wire async_rstb = ((RESETMODE_B == "ASYNC") ? rstb : ((RESETMODE_B == "ARSR") ? rstb_p3 : 0)) ;
|
||||||
|
/* verilator lint_off WIDTHEXPAND */
|
||||||
|
wire ssroverce_b = ((SSROVERCE_B == "ENABLE") && sync_rstb) ;
|
||||||
|
wire ceoverssr_b = ((SSROVERCE_B == "DISABLE") && sync_rstb) ;
|
||||||
|
always
|
||||||
|
@(posedge clkb or
|
||||||
|
posedge async_rstb)
|
||||||
|
begin
|
||||||
|
if (async_rstb)
|
||||||
|
begin
|
||||||
|
dob_tmp2 <= INITVAL_B ;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if (ssroverce_b)
|
||||||
|
begin
|
||||||
|
dob_tmp2 <= INITVAL_B ;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if (oceb)
|
||||||
|
begin
|
||||||
|
if (ceoverssr_b)
|
||||||
|
begin
|
||||||
|
dob_tmp2 <= INITVAL_B ;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
dob_tmp2 <= dob_tmp ;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
always
|
||||||
|
@(posedge clkb or
|
||||||
|
posedge async_rstb)
|
||||||
|
begin
|
||||||
|
if (async_rstb)
|
||||||
|
begin
|
||||||
|
dob_tmp <= INITVAL_B ;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if (sync_rstb)
|
||||||
|
begin
|
||||||
|
dob_tmp <= INITVAL_B ;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
if (ceb)
|
||||||
|
begin
|
||||||
|
if ((MODE == "DP"))
|
||||||
|
begin
|
||||||
|
read_b (addrb,
|
||||||
|
dib,
|
||||||
|
web) ;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if ((MODE == "SDP"))
|
||||||
|
begin
|
||||||
|
read_b (addrb,
|
||||||
|
dib,
|
||||||
|
1'b0) ;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
assign doa = ((REGMODE_A == "OUTREG") ? doa_tmp2 : doa_tmp) ;
|
||||||
|
assign dob = ((REGMODE_B == "OUTREG") ? dob_tmp2 : dob_tmp) ;
|
||||||
|
task write_a(
|
||||||
|
input reg [(ADDRWIDTH_A - 1):0] addr,
|
||||||
|
|
||||||
|
input reg [(DATAWIDTH_A - 1):0] data,
|
||||||
|
|
||||||
|
input reg [(WEA_WIDTH - 1):0] we) ;
|
||||||
|
/* verilator lint_off VARHIDDEN */
|
||||||
|
integer i,
|
||||||
|
j ;
|
||||||
|
begin
|
||||||
|
if ((USE_BYTE_WEA != 0))
|
||||||
|
begin
|
||||||
|
for (i = 0 ; (i < WIDTHRATIO_A) ; i = (i + 1))
|
||||||
|
begin
|
||||||
|
for (j = 0 ; (j < (WEA_WIDTH / WIDTHRATIO_A)) ; j = (j + 1))
|
||||||
|
begin
|
||||||
|
if (we[(((i * WEA_WIDTH) / WIDTHRATIO_A) + j)])
|
||||||
|
begin
|
||||||
|
memory[((addr * WIDTHRATIO_A) + i)][(j * BYTE_SIZE) +: BYTE_SIZE] <= data[((i * MIN_WIDTH) + (j * BYTE_SIZE)) +: BYTE_SIZE] ;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
if (we)
|
||||||
|
begin
|
||||||
|
for (i = 0 ; (i < WIDTHRATIO_A) ; i = (i + 1))
|
||||||
|
begin
|
||||||
|
memory[((addr * WIDTHRATIO_A) + i)] <= data[(i * MIN_WIDTH) +: MIN_WIDTH] ;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
task write_b(
|
||||||
|
input reg [(ADDRWIDTH_B - 1):0] addr,
|
||||||
|
|
||||||
|
input reg [(DATAWIDTH_B - 1):0] data,
|
||||||
|
|
||||||
|
input reg [(WEB_WIDTH - 1):0] we) ;
|
||||||
|
/* verilator lint_off VARHIDDEN */
|
||||||
|
integer i,
|
||||||
|
j ;
|
||||||
|
begin
|
||||||
|
if ((USE_BYTE_WEB != 0))
|
||||||
|
begin
|
||||||
|
for (i = 0 ; (i < WIDTHRATIO_B) ; i = (i + 1))
|
||||||
|
begin
|
||||||
|
for (j = 0 ; (j < (WEB_WIDTH / WIDTHRATIO_B)) ; j = (j + 1))
|
||||||
|
begin
|
||||||
|
if (we[(((i * WEB_WIDTH) / WIDTHRATIO_B) + j)])
|
||||||
|
begin
|
||||||
|
memory[((addr * WIDTHRATIO_B) + i)][(j * BYTE_SIZE) +: BYTE_SIZE] <= data[((i * MIN_WIDTH) + (j * BYTE_SIZE)) +: BYTE_SIZE] ;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
if (we)
|
||||||
|
begin
|
||||||
|
for (i = 0 ; (i < WIDTHRATIO_B) ; i = (i + 1))
|
||||||
|
begin
|
||||||
|
memory[((addr * WIDTHRATIO_B) + i)] <= data[(i * MIN_WIDTH) +: MIN_WIDTH] ;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
task read_a(
|
||||||
|
input reg [(ADDRWIDTH_A - 1):0] addr,
|
||||||
|
|
||||||
|
input reg [(DATAWIDTH_A - 1):0] data,
|
||||||
|
|
||||||
|
input reg [(WEA_WIDTH - 1):0] we) ;
|
||||||
|
integer i,
|
||||||
|
j ;
|
||||||
|
if ((USE_BYTE_WEA != 0))
|
||||||
|
begin
|
||||||
|
if ((WRITEMODE_A == "NORMAL"))
|
||||||
|
begin
|
||||||
|
for (i = 0 ; (i < WIDTHRATIO_A) ; i = (i + 1))
|
||||||
|
begin
|
||||||
|
for (j = 0 ; (j < (WEA_WIDTH / WIDTHRATIO_A)) ; j = (j + 1))
|
||||||
|
begin
|
||||||
|
if ((!we[(((i * WEA_WIDTH) / WIDTHRATIO_A) + j)]))
|
||||||
|
begin
|
||||||
|
doa_tmp[((i * MIN_WIDTH) + (j * BYTE_SIZE)) +: BYTE_SIZE] <= memory[((addr * WIDTHRATIO_A) + i)][(j * BYTE_SIZE) +: BYTE_SIZE] ;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
/* verilator lint_off WIDTHEXPAND */
|
||||||
|
if ((WRITEMODE_A == "WRITETHROUGH"))
|
||||||
|
begin
|
||||||
|
for (i = 0 ; (i < WIDTHRATIO_A) ; i = (i + 1))
|
||||||
|
begin
|
||||||
|
for (j = 0 ; (j < (WEA_WIDTH / WIDTHRATIO_A)) ; j = (j + 1))
|
||||||
|
begin
|
||||||
|
if (we[(((i * WEA_WIDTH) / WIDTHRATIO_A) + j)])
|
||||||
|
begin
|
||||||
|
doa_tmp[((i * MIN_WIDTH) + (j * BYTE_SIZE)) +: BYTE_SIZE] <= data[((i * MIN_WIDTH) + (j * BYTE_SIZE)) +: BYTE_SIZE] ;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
doa_tmp[((i * MIN_WIDTH) + (j * BYTE_SIZE)) +: BYTE_SIZE] <= memory[((addr * WIDTHRATIO_A) + i)][(j * BYTE_SIZE) +: BYTE_SIZE] ;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
for (i = 0 ; (i < WIDTHRATIO_A) ; i = (i + 1))
|
||||||
|
begin
|
||||||
|
doa_tmp[(MIN_WIDTH * i) +: MIN_WIDTH] <= memory[((addr * WIDTHRATIO_A) + i)] ;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
if ((WRITEMODE_A == "NORMAL"))
|
||||||
|
begin
|
||||||
|
if ((!we[0]))
|
||||||
|
begin
|
||||||
|
for (i = 0 ; (i < WIDTHRATIO_A) ; i = (i + 1))
|
||||||
|
begin
|
||||||
|
doa_tmp[(MIN_WIDTH * i) +: MIN_WIDTH] <= memory[((addr * WIDTHRATIO_A) + i)] ;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
/* verilator lint_off WIDTHEXPAND */
|
||||||
|
if ((WRITEMODE_A == "WRITETHROUGH"))
|
||||||
|
begin
|
||||||
|
if (we[0])
|
||||||
|
begin
|
||||||
|
doa_tmp <= data ;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
for (i = 0 ; (i < WIDTHRATIO_A) ; i = (i + 1))
|
||||||
|
begin
|
||||||
|
doa_tmp[(MIN_WIDTH * i) +: MIN_WIDTH] <= memory[((addr * WIDTHRATIO_A) + i)] ;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
for (i = 0 ; (i < WIDTHRATIO_A) ; i = (i + 1))
|
||||||
|
begin
|
||||||
|
doa_tmp[(MIN_WIDTH * i) +: MIN_WIDTH] <= memory[((addr * WIDTHRATIO_A) + i)] ;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
task read_b(
|
||||||
|
input reg [(ADDRWIDTH_B - 1):0] addr,
|
||||||
|
|
||||||
|
input reg [(DATAWIDTH_B - 1):0] data,
|
||||||
|
|
||||||
|
input reg [(WEB_WIDTH - 1):0] we) ;
|
||||||
|
integer i,
|
||||||
|
j ;
|
||||||
|
if ((USE_BYTE_WEB != 0))
|
||||||
|
begin
|
||||||
|
if ((WRITEMODE_B == "NORMAL"))
|
||||||
|
begin
|
||||||
|
for (i = 0 ; (i < WIDTHRATIO_B) ; i = (i + 1))
|
||||||
|
begin
|
||||||
|
for (j = 0 ; (j < (WEB_WIDTH / WIDTHRATIO_B)) ; j = (j + 1))
|
||||||
|
begin
|
||||||
|
if ((!we[(((i * WEB_WIDTH) / WIDTHRATIO_B) + j)]))
|
||||||
|
begin
|
||||||
|
dob_tmp[((i * MIN_WIDTH) + (j * BYTE_SIZE)) +: BYTE_SIZE] <= memory[((addr * WIDTHRATIO_B) + i)][(j * BYTE_SIZE) +: BYTE_SIZE] ;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if ((WRITEMODE_B == "WRITETHROUGH"))
|
||||||
|
begin
|
||||||
|
for (i = 0 ; (i < WIDTHRATIO_B) ; i = (i + 1))
|
||||||
|
begin
|
||||||
|
for (j = 0 ; (j < (WEB_WIDTH / WIDTHRATIO_B)) ; j = (j + 1))
|
||||||
|
begin
|
||||||
|
if (we[(((i * WEB_WIDTH) / WIDTHRATIO_B) + j)])
|
||||||
|
begin
|
||||||
|
dob_tmp[((i * MIN_WIDTH) + (j * BYTE_SIZE)) +: BYTE_SIZE] <= data[((i * MIN_WIDTH) + (j * BYTE_SIZE)) +: BYTE_SIZE] ;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
dob_tmp[((i * MIN_WIDTH) + (j * BYTE_SIZE)) +: BYTE_SIZE] <= memory[((addr * WIDTHRATIO_B) + i)][(j * BYTE_SIZE) +: BYTE_SIZE] ;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
for (i = 0 ; (i < WIDTHRATIO_B) ; i = (i + 1))
|
||||||
|
begin
|
||||||
|
dob_tmp[(MIN_WIDTH * i) +: MIN_WIDTH] <= memory[((addr * WIDTHRATIO_B) + i)] ;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
if ((WRITEMODE_B == "NORMAL"))
|
||||||
|
begin
|
||||||
|
if ((!we[0]))
|
||||||
|
begin
|
||||||
|
for (i = 0 ; (i < WIDTHRATIO_B) ; i = (i + 1))
|
||||||
|
begin
|
||||||
|
dob_tmp[(MIN_WIDTH * i) +: MIN_WIDTH] <= memory[((addr * WIDTHRATIO_B) + i)] ;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if ((WRITEMODE_B == "WRITETHROUGH"))
|
||||||
|
begin
|
||||||
|
if (we[0])
|
||||||
|
begin
|
||||||
|
dob_tmp <= data ;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
for (i = 0 ; (i < WIDTHRATIO_B) ; i = (i + 1))
|
||||||
|
begin
|
||||||
|
dob_tmp[(MIN_WIDTH * i) +: MIN_WIDTH] <= memory[((addr * WIDTHRATIO_B) + i)] ;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
for (i = 0 ; (i < WIDTHRATIO_B) ; i = (i + 1))
|
||||||
|
begin
|
||||||
|
dob_tmp[(MIN_WIDTH * i) +: MIN_WIDTH] <= memory[((addr * WIDTHRATIO_B) + i)] ;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
async_fifo.v
|
|
||||||
fifomem.v
|
|
||||||
fifomem_dp.v
|
|
||||||
hdl.list
|
|
||||||
rptr_empty.v
|
|
||||||
sync_ptr.v
|
|
||||||
sync_r2w.v
|
|
||||||
sync_w2r.v
|
|
||||||
wptr_full.v
|
|
|
@ -1,98 +0,0 @@
|
||||||
// distributed under the mit license
|
|
||||||
// https://opensource.org/licenses/mit-license.php
|
|
||||||
|
|
||||||
`timescale 1 ns / 1 ps
|
|
||||||
`default_nettype none
|
|
||||||
|
|
||||||
module async_fifo
|
|
||||||
|
|
||||||
#(
|
|
||||||
parameter DSIZE = 8,
|
|
||||||
parameter ASIZE = 4,
|
|
||||||
parameter FALLTHROUGH = "TRUE" // First word fall-through without latency
|
|
||||||
)(
|
|
||||||
input wire wclk,
|
|
||||||
input wire wrst_n,
|
|
||||||
input wire winc,
|
|
||||||
input wire [DSIZE-1:0] wdata,
|
|
||||||
output wire wfull,
|
|
||||||
output wire awfull,
|
|
||||||
input wire rclk,
|
|
||||||
input wire rrst_n,
|
|
||||||
input wire rinc,
|
|
||||||
output wire [DSIZE-1:0] rdata,
|
|
||||||
output wire rempty,
|
|
||||||
output wire arempty
|
|
||||||
);
|
|
||||||
|
|
||||||
wire [ASIZE-1:0] waddr, raddr;
|
|
||||||
wire [ASIZE :0] wptr, rptr, wq2_rptr, rq2_wptr;
|
|
||||||
|
|
||||||
// The module synchronizing the read point
|
|
||||||
// from read to write domain
|
|
||||||
sync_r2w
|
|
||||||
#(ASIZE)
|
|
||||||
sync_r2w (
|
|
||||||
.wq2_rptr (wq2_rptr),
|
|
||||||
.rptr (rptr),
|
|
||||||
.wclk (wclk),
|
|
||||||
.wrst_n (wrst_n)
|
|
||||||
);
|
|
||||||
|
|
||||||
// The module synchronizing the write point
|
|
||||||
// from write to read domain
|
|
||||||
sync_w2r
|
|
||||||
#(ASIZE)
|
|
||||||
sync_w2r (
|
|
||||||
.rq2_wptr (rq2_wptr),
|
|
||||||
.wptr (wptr),
|
|
||||||
.rclk (rclk),
|
|
||||||
.rrst_n (rrst_n)
|
|
||||||
);
|
|
||||||
|
|
||||||
// The module handling the write requests
|
|
||||||
wptr_full
|
|
||||||
#(ASIZE)
|
|
||||||
wptr_full (
|
|
||||||
.awfull (awfull),
|
|
||||||
.wfull (wfull),
|
|
||||||
.waddr (waddr),
|
|
||||||
.wptr (wptr),
|
|
||||||
.wq2_rptr (wq2_rptr),
|
|
||||||
.winc (winc),
|
|
||||||
.wclk (wclk),
|
|
||||||
.wrst_n (wrst_n)
|
|
||||||
);
|
|
||||||
|
|
||||||
// The DC-RAM
|
|
||||||
fifomem
|
|
||||||
#(DSIZE, ASIZE, FALLTHROUGH)
|
|
||||||
fifomem (
|
|
||||||
.rclken (rinc),
|
|
||||||
.rclk (rclk),
|
|
||||||
.rdata (rdata),
|
|
||||||
.wdata (wdata),
|
|
||||||
.waddr (waddr),
|
|
||||||
.raddr (raddr),
|
|
||||||
.wclken (winc),
|
|
||||||
.wfull (wfull),
|
|
||||||
.wclk (wclk)
|
|
||||||
);
|
|
||||||
|
|
||||||
// The module handling read requests
|
|
||||||
rptr_empty
|
|
||||||
#(ASIZE)
|
|
||||||
rptr_empty (
|
|
||||||
.arempty (arempty),
|
|
||||||
.rempty (rempty),
|
|
||||||
.raddr (raddr),
|
|
||||||
.rptr (rptr),
|
|
||||||
.rq2_wptr (rq2_wptr),
|
|
||||||
.rinc (rinc),
|
|
||||||
.rclk (rclk),
|
|
||||||
.rrst_n (rrst_n)
|
|
||||||
);
|
|
||||||
|
|
||||||
endmodule
|
|
||||||
|
|
||||||
`resetall
|
|
|
@ -1,52 +0,0 @@
|
||||||
// distributed under the mit license
|
|
||||||
// https://opensource.org/licenses/mit-license.php
|
|
||||||
|
|
||||||
`timescale 1 ns / 1 ps
|
|
||||||
`default_nettype none
|
|
||||||
|
|
||||||
module fifomem
|
|
||||||
|
|
||||||
#(
|
|
||||||
parameter DATASIZE = 8, // Memory data word width
|
|
||||||
parameter ADDRSIZE = 4, // Number of mem address bits
|
|
||||||
parameter FALLTHROUGH = "TRUE" // First word fall-through
|
|
||||||
) (
|
|
||||||
input wire wclk,
|
|
||||||
input wire wclken,
|
|
||||||
input wire [ADDRSIZE-1:0] waddr,
|
|
||||||
input wire [DATASIZE-1:0] wdata,
|
|
||||||
input wire wfull,
|
|
||||||
input wire rclk,
|
|
||||||
input wire rclken,
|
|
||||||
input wire [ADDRSIZE-1:0] raddr,
|
|
||||||
output wire [DATASIZE-1:0] rdata
|
|
||||||
);
|
|
||||||
|
|
||||||
localparam DEPTH = 1<<ADDRSIZE;
|
|
||||||
|
|
||||||
reg [DATASIZE-1:0] mem [0:DEPTH-1];
|
|
||||||
reg [DATASIZE-1:0] rdata_r;
|
|
||||||
|
|
||||||
always @(posedge wclk) begin
|
|
||||||
if (wclken && !wfull)
|
|
||||||
mem[waddr] <= wdata;
|
|
||||||
end
|
|
||||||
|
|
||||||
generate
|
|
||||||
if (FALLTHROUGH == "TRUE")
|
|
||||||
begin : fallthrough
|
|
||||||
assign rdata = mem[raddr];
|
|
||||||
end
|
|
||||||
else
|
|
||||||
begin : registered_read
|
|
||||||
always @(posedge rclk) begin
|
|
||||||
if (rclken)
|
|
||||||
rdata_r <= mem[raddr];
|
|
||||||
end
|
|
||||||
assign rdata = rdata_r;
|
|
||||||
end
|
|
||||||
endgenerate
|
|
||||||
|
|
||||||
endmodule
|
|
||||||
|
|
||||||
`resetall
|
|
|
@ -1,95 +0,0 @@
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Copyright 2017 Damien Pretet ThotIP
|
|
||||||
// Copyright 2018 Julius Baxter
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
`timescale 1 ns / 1 ps
|
|
||||||
`default_nettype none
|
|
||||||
|
|
||||||
module fifomem_dp
|
|
||||||
|
|
||||||
#(
|
|
||||||
parameter DATASIZE = 8, // Memory data word width
|
|
||||||
parameter ADDRSIZE = 4, // Number of mem address bits
|
|
||||||
parameter FALLTHROUGH = "TRUE" // First word fall-through
|
|
||||||
) (
|
|
||||||
input wire a_clk,
|
|
||||||
input wire [DATASIZE-1:0] a_wdata,
|
|
||||||
output wire [DATASIZE-1:0] a_rdata,
|
|
||||||
input wire [ADDRSIZE-1:0] a_addr,
|
|
||||||
input wire a_rinc,
|
|
||||||
input wire a_winc,
|
|
||||||
|
|
||||||
input wire b_clk,
|
|
||||||
input wire [DATASIZE-1:0] b_wdata,
|
|
||||||
output wire [DATASIZE-1:0] b_rdata,
|
|
||||||
input wire [ADDRSIZE-1:0] b_addr,
|
|
||||||
input wire b_rinc,
|
|
||||||
input wire b_winc
|
|
||||||
);
|
|
||||||
|
|
||||||
reg [DATASIZE-1:0] a_rdata_r;
|
|
||||||
reg [DATASIZE-1:0] b_rdata_r;
|
|
||||||
|
|
||||||
generate
|
|
||||||
|
|
||||||
localparam DEPTH = 1<<ADDRSIZE;
|
|
||||||
reg [DATASIZE-1:0] mem [0:DEPTH-1];
|
|
||||||
|
|
||||||
if (FALLTHROUGH == "TRUE") begin : fallthrough
|
|
||||||
|
|
||||||
always @(posedge a_clk)
|
|
||||||
if (a_winc)
|
|
||||||
mem[a_addr] <= a_wdata;
|
|
||||||
|
|
||||||
assign a_rdata = mem[a_addr];
|
|
||||||
|
|
||||||
always @(posedge b_clk)
|
|
||||||
if (b_winc)
|
|
||||||
mem[b_addr] <= b_wdata;
|
|
||||||
|
|
||||||
assign b_rdata = mem[b_addr];
|
|
||||||
|
|
||||||
end else begin : registered
|
|
||||||
|
|
||||||
wire a_en = a_rinc | a_winc;
|
|
||||||
|
|
||||||
always @(posedge a_clk)
|
|
||||||
if (a_en) begin
|
|
||||||
if (a_winc)
|
|
||||||
mem[a_addr] <= a_wdata;
|
|
||||||
a_rdata_r <= mem[a_addr];
|
|
||||||
end
|
|
||||||
|
|
||||||
assign a_rdata = a_rdata_r;
|
|
||||||
|
|
||||||
wire b_en = b_rinc | b_winc;
|
|
||||||
|
|
||||||
always @(posedge b_clk)
|
|
||||||
if (b_en) begin
|
|
||||||
if (b_winc)
|
|
||||||
mem[b_addr] <= b_wdata;
|
|
||||||
b_rdata_r <= mem[b_addr];
|
|
||||||
end
|
|
||||||
|
|
||||||
assign b_rdata = b_rdata_r;
|
|
||||||
|
|
||||||
end // block: registered
|
|
||||||
endgenerate
|
|
||||||
|
|
||||||
|
|
||||||
endmodule
|
|
||||||
|
|
||||||
`resetall
|
|
|
@ -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 rptr_empty
|
|
||||||
|
|
||||||
#(
|
|
||||||
parameter ADDRSIZE = 4
|
|
||||||
)(
|
|
||||||
input wire rclk,
|
|
||||||
input wire rrst_n,
|
|
||||||
input wire rinc,
|
|
||||||
input wire [ADDRSIZE :0] rq2_wptr,
|
|
||||||
output reg rempty,
|
|
||||||
output reg arempty,
|
|
||||||
output wire [ADDRSIZE-1:0] raddr,
|
|
||||||
output reg [ADDRSIZE :0] rptr
|
|
||||||
);
|
|
||||||
|
|
||||||
reg [ADDRSIZE:0] rbin;
|
|
||||||
wire [ADDRSIZE:0] rgraynext, rbinnext, rgraynextm1;
|
|
||||||
wire arempty_val, rempty_val;
|
|
||||||
|
|
||||||
//-------------------
|
|
||||||
// GRAYSTYLE2 pointer
|
|
||||||
//-------------------
|
|
||||||
always @(posedge rclk or negedge rrst_n) begin
|
|
||||||
|
|
||||||
if (!rrst_n)
|
|
||||||
{rbin, rptr} <= 0;
|
|
||||||
else
|
|
||||||
{rbin, rptr} <= {rbinnext, rgraynext};
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
// Memory read-address pointer (okay to use binary to address memory)
|
|
||||||
assign raddr = rbin[ADDRSIZE-1:0];
|
|
||||||
assign rbinnext = rbin + {{(ADDRSIZE - 1){1'b0}},(rinc & ~rempty)};
|
|
||||||
assign rgraynext = (rbinnext >> 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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -12,15 +12,34 @@ module chanels_to_RGB #(
|
||||||
input [15:0] data_in [2:0], // 0:R 1:G 2:B
|
input [15:0] data_in [2:0], // 0:R 1:G 2:B
|
||||||
|
|
||||||
// 输出相关
|
// 输出相关
|
||||||
input data_que, // 数据请求
|
input out_que, // 数据请求
|
||||||
output out_en,
|
output out_en,
|
||||||
output [3 * OUT_DEPTH - 1:0] data_out
|
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 [31:0] data_cal [2:0]; // 用于保存运算结果,防止溢出
|
||||||
reg fifo_en;
|
reg fifo_en;
|
||||||
reg [3 * OUT_DEPTH - 1:0] fifo_in; // 输入fifo中缓存
|
reg [3 * OUT_DEPTH - 1:0] fifo_in; // 输入fifo中缓存
|
||||||
wire fifo_empty;
|
wire fifo_empty, fifo_que;
|
||||||
// wire fifo_alempty;
|
|
||||||
|
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
|
always @(posedge clk or posedge reset) begin
|
||||||
if (reset) begin
|
if (reset) begin
|
||||||
|
@ -32,43 +51,52 @@ module chanels_to_RGB #(
|
||||||
fifo_in <= 0;
|
fifo_in <= 0;
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
if (in_en) begin
|
case (state)
|
||||||
data_cal[0] <= data_in[0] * OUT_DEPTH / IN_DEPTH;
|
READ_DATA: begin
|
||||||
data_cal[1] <= data_in[1] * OUT_DEPTH / IN_DEPTH;
|
fifo_en <= 0;
|
||||||
data_cal[2] <= data_in[2] * OUT_DEPTH / IN_DEPTH;
|
|
||||||
|
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]};
|
end
|
||||||
// data_out <= {data_cal[0][OUT_DEPTH - 1:0], data_cal[1][OUT_DEPTH - 1:0],data_cal[2][OUT_DEPTH - 1:0]};
|
end
|
||||||
end
|
|
||||||
fifo_en <= in_en;
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
// 存在数据请求且FIFO不为空时,才发送数据
|
// 存在数据请求且FIFO不为空时,才发送数据
|
||||||
assign out_en = (data_que && !fifo_empty) ? 1 : 0;
|
assign fifo_que = (out_que && !fifo_empty) ? 1 : 0;
|
||||||
|
|
||||||
async_fifo #(
|
SOFTFIFO #(
|
||||||
.DSIZE(3 * OUT_DEPTH),
|
.DATA_WIDTH_W(3 * OUT_DEPTH),
|
||||||
.ASIZE(4),
|
.DATA_WIDTH_R(3 * OUT_DEPTH)
|
||||||
.FALLTHROUGH("False")
|
|
||||||
) RGB_FIFO (
|
) RGB_FIFO (
|
||||||
.wclk(clk),
|
.rst(reset), //asynchronous port,active hight
|
||||||
.rclk(clk),
|
.clkw(clk), //write clock
|
||||||
.wrst_n(reset),
|
.clkr(clk), //read clock
|
||||||
.rrst_n(reset),
|
.we(fifo_en), //write enable,active hight
|
||||||
|
.di(fifo_in), //write data
|
||||||
.winc(fifo_en),
|
.re(fifo_que), //read enable,active hight
|
||||||
.wdata(fifo_in),
|
.dout(data_out), //read data
|
||||||
/* verilator lint_off PINCONNECTEMPTY */
|
.valid(out_en), //read data valid flag
|
||||||
.wfull(),
|
/* verilator lint_off PINCONNECTEMPTY */
|
||||||
/* verilator lint_off PINCONNECTEMPTY */
|
.full_flag(), //fifo full flag
|
||||||
.awfull(),
|
.empty_flag(fifo_empty), //fifo empty flag
|
||||||
|
/* verilator lint_off PINCONNECTEMPTY */
|
||||||
/* verilator lint_off PINCONNECTEMPTY */
|
.afull(), //fifo almost full flag
|
||||||
.arempty(),
|
/* verilator lint_off PINCONNECTEMPTY */
|
||||||
.rempty(fifo_empty),
|
.aempty(), //fifo almost empty flag
|
||||||
.rdata(data_out),
|
/* verilator lint_off PINCONNECTEMPTY */
|
||||||
.rinc(out_en)
|
.wrusedw(), //stored data number in fifo
|
||||||
|
/* verilator lint_off PINCONNECTEMPTY */
|
||||||
|
.rdusedw() //available data number for read
|
||||||
);
|
);
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
2
isp.v
2
isp.v
|
@ -60,7 +60,7 @@ module isp #(
|
||||||
.in_en(rgb_en),
|
.in_en(rgb_en),
|
||||||
.data_in({im_red, im_green, im_blue}),
|
.data_in({im_red, im_green, im_blue}),
|
||||||
|
|
||||||
.data_que(scale_in_que),
|
.out_que(scale_in_que),
|
||||||
.out_en(scale_in_en),
|
.out_en(scale_in_en),
|
||||||
.data_out(scale_in_data)
|
.data_out(scale_in_data)
|
||||||
);
|
);
|
||||||
|
|
|
@ -65,6 +65,9 @@ SC_MODULE (TB_ISP) {
|
||||||
data_out[1].write(image[( pos_y + 1 ) * IM_WIDTH + pos_x]);
|
data_out[1].write(image[( pos_y + 1 ) * IM_WIDTH + pos_x]);
|
||||||
data_out[2].write(image[( pos_y + 2 ) * 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) {
|
if (pos_x++ >= IM_WIDTH) {
|
||||||
pos_x = 0;
|
pos_x = 0;
|
||||||
pos_y++;
|
pos_y++;
|
||||||
|
@ -101,7 +104,7 @@ int sc_main(int argc, char* argv[]) {
|
||||||
// Open image
|
// Open image
|
||||||
ifstream in_image;
|
ifstream in_image;
|
||||||
ofstream out_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);
|
out_image.open("./out.bin", ios::out | ios::binary);
|
||||||
if (!in_image.is_open()) {
|
if (!in_image.is_open()) {
|
||||||
cout << "Open image fail" << endl;
|
cout << "Open image fail" << endl;
|
||||||
|
@ -113,6 +116,7 @@ int sc_main(int argc, char* argv[]) {
|
||||||
// Read image
|
// Read image
|
||||||
// uint8_t buf[IM_SIZE * 2] = {0};
|
// uint8_t buf[IM_SIZE * 2] = {0};
|
||||||
auto buf = make_unique<uint8_t[]>(2 * IM_SIZE);
|
auto buf = make_unique<uint8_t[]>(2 * IM_SIZE);
|
||||||
|
// vector<vector<uint8_t>> buf(IM_HEIGHT, vector<uint8_t>(IM_WIDTH, 0));
|
||||||
in_image.read((char*)buf.get(), IM_SIZE * 2);
|
in_image.read((char*)buf.get(), IM_SIZE * 2);
|
||||||
in_image.close();
|
in_image.close();
|
||||||
// Reshape data
|
// Reshape data
|
||||||
|
|
Loading…
Reference in New Issue