reconstruct some modules
This commit is contained in:
parent
daf1f454fe
commit
87d73b203a
|
@ -0,0 +1,86 @@
|
||||||
|
`timescale 1ns / 1ps
|
||||||
|
|
||||||
|
// 三通道图像合成一个RGB图像
|
||||||
|
module ColorBlender #(
|
||||||
|
parameter reg [ 4:0] IN_DEPTH = 12, // 输入图像的色深
|
||||||
|
parameter reg [ 4:0] OUT_DEPTH = 8, // 输出图像的色深
|
||||||
|
parameter reg [12:0] GAIN_RED = 120, // 红色增益系数(除以10^小数位数)
|
||||||
|
parameter reg [12:0] GAIN_GREEN = 50, // 绿色增益系数
|
||||||
|
parameter reg [12:0] GAIN_BLUE = 95, // 蓝色增益系数
|
||||||
|
parameter reg [ 4:0] GAIN_OFFSET = 7
|
||||||
|
) (
|
||||||
|
input clk,
|
||||||
|
input reset,
|
||||||
|
|
||||||
|
input in_en,
|
||||||
|
input [15:0] data_in[2], // 0:R 1:G 2:B
|
||||||
|
output out_ready,
|
||||||
|
output out_receive,
|
||||||
|
|
||||||
|
// 输出相关
|
||||||
|
input in_ready,
|
||||||
|
input in_receive,
|
||||||
|
output out_en,
|
||||||
|
output [3 * OUT_DEPTH - 1:0] data_out,
|
||||||
|
|
||||||
|
// 颜色校正
|
||||||
|
input wire color_correction
|
||||||
|
);
|
||||||
|
localparam READ_DATA = 0;
|
||||||
|
localparam CALC_DATA = 1;
|
||||||
|
localparam SEND_DATA = 2;
|
||||||
|
|
||||||
|
reg [2:0] state, nextState;
|
||||||
|
reg [31:0] data_cal[2]; // 用于保存运算结果,防止溢出
|
||||||
|
|
||||||
|
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) ? (color_correction ? CALC_DATA : SEND_DATA) : READ_DATA;
|
||||||
|
CALC_DATA: nextState = SEND_DATA;
|
||||||
|
SEND_DATA: nextState = READ_DATA;
|
||||||
|
default: nextState = READ_DATA;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
assign out_ready = (state == READ_DATA) ? 1 : 0;
|
||||||
|
assign out_receive = in_en ? 1 : 0;
|
||||||
|
assign out_en = (in_ready && state == SEND_DATA) ? 1 : 0;
|
||||||
|
|
||||||
|
always @(posedge clk or posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
// 初始化
|
||||||
|
data_cal[0] <= 0;
|
||||||
|
data_cal[1] <= 0;
|
||||||
|
data_cal[2] <= 0;
|
||||||
|
end else begin
|
||||||
|
case (state)
|
||||||
|
READ_DATA: begin
|
||||||
|
|
||||||
|
if (in_en) begin
|
||||||
|
data_cal[0] <= ({{(32 - IN_DEPTH){1'b0}}, data_in[0]} >> (IN_DEPTH - OUT_DEPTH));
|
||||||
|
data_cal[1] <= ({{(32 - IN_DEPTH){1'b0}}, data_in[1]} >> (IN_DEPTH - OUT_DEPTH));
|
||||||
|
data_cal[2] <= ({{(32 - IN_DEPTH){1'b0}}, data_in[2]} >> (IN_DEPTH - OUT_DEPTH));
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
CALC_DATA: begin
|
||||||
|
end
|
||||||
|
|
||||||
|
SEND_DATA: begin
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
default: ;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
|
@ -1,47 +1,49 @@
|
||||||
module demosaic2 #(
|
module demosaic2 #(
|
||||||
parameter IM_WIDTH = 512, // 图像宽度
|
parameter reg [16:0] IM_WIDTH = 512, // 图像宽度
|
||||||
parameter IM_HEIGHT = 256, // 图像高度
|
parameter reg [16:0] IM_HEIGHT = 256, // 图像高度
|
||||||
parameter RAW_TYPE = 3, // 0:grbg 1:rggb 2:bggr 3:gbrg
|
parameter reg [1:0] RAW_TYPE = 3, // 0:grbg 1:rggb 2:bggr 3:gbrg
|
||||||
parameter DATA_SIZE = 16
|
parameter reg [5:0] DATA_SIZE = 16
|
||||||
) (
|
) (
|
||||||
// 基本信号
|
// 基本信号
|
||||||
input clk,
|
input clk,
|
||||||
input reset,
|
input reset,
|
||||||
|
|
||||||
// 数据输入信号
|
// 数据输入信号
|
||||||
input data_en,
|
input in_en,
|
||||||
input [DATA_SIZE - 1:0] data_in [2:0], // 数据输入线,0、1、2分别表示第一、二、三行
|
input [DATA_SIZE - 1:0] in_data [2], // 数据输入线,0、1、2分别表示第一、二、三行
|
||||||
output reg data_que, // 数据请求线,高电平:请求三个数据,直到读取完才拉低
|
output out_ready, // 数据请求线,高电平:请求三个数据,直到读取完才拉低
|
||||||
|
output out_receive,
|
||||||
|
|
||||||
// en: 输出数据有效信号,高电平有效
|
// en: 输出数据有效信号,高电平有效
|
||||||
output reg out_en,
|
input in_ready,
|
||||||
|
input in_receive,
|
||||||
|
output out_en,
|
||||||
output reg [DATA_SIZE - 1:0] out_r,
|
output reg [DATA_SIZE - 1:0] out_r,
|
||||||
output reg [DATA_SIZE - 1:0] out_g,
|
output reg [DATA_SIZE - 1:0] out_g,
|
||||||
output reg [DATA_SIZE - 1:0] out_b
|
output reg [DATA_SIZE - 1:0] out_b
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// 常量,包括状态机
|
// 常量,包括状态机
|
||||||
// localparam IM_SIZE = IM_HEIGHT * IM_WIDTH;
|
// localparam IM_SIZE = IM_HEIGHT * IM_WIDTH;
|
||||||
localparam READ_DATA = 0;
|
localparam READ_DATA = 0;
|
||||||
localparam COLOR_GEN = 1;
|
localparam COLOR_GEN = 1;
|
||||||
localparam WRITE_DATA = 2;
|
localparam SEND_DATA = 2;
|
||||||
localparam SLIDE_WINDOW = 3;
|
localparam SLIDE_WINDOW = 3;
|
||||||
|
|
||||||
// 寄存器
|
// 寄存器
|
||||||
reg [2:0] state, nextState;
|
reg [2:0] state, nextState;
|
||||||
reg [15:0] data_cache [2:0][2:0]; // 缓存颜色数据,行列3x3
|
reg [15:0] data_cache[2][2]; // 缓存颜色数据,行列3x3
|
||||||
reg [11:0] pos_x, pos_y; // 滑动窗口左上角位置
|
reg [11:0] pos_x, pos_y; // 滑动窗口左上角位置
|
||||||
reg [1:0] cnt_data; // 记录输入数据数量,最大值256
|
reg [2:0] cnt_data; // 记录输入数据数量,最大值256
|
||||||
reg [1:0] raw_type;
|
reg [1:0] raw_type;
|
||||||
reg [15:0] red, blue, green;
|
reg [15:0] red, blue, green;
|
||||||
|
|
||||||
// 三段状态机实现,窗口滑动,颜色计算
|
// 三段状态机实现,窗口滑动,颜色计算
|
||||||
// 状态切换
|
// 状态切换
|
||||||
always @(posedge clk or posedge reset) begin
|
always @(posedge clk or posedge reset) begin
|
||||||
if (reset)
|
if (reset) state <= READ_DATA;
|
||||||
state <= READ_DATA;
|
else state <= nextState;
|
||||||
else
|
|
||||||
state <= nextState;
|
|
||||||
end
|
end
|
||||||
|
|
||||||
// 下一状态更新
|
// 下一状态更新
|
||||||
|
@ -49,12 +51,20 @@ module demosaic2 #(
|
||||||
case (state)
|
case (state)
|
||||||
// 记录够3x3个数据后,进行rgb转换
|
// 记录够3x3个数据后,进行rgb转换
|
||||||
READ_DATA: nextState = (cnt_data >= 3) ? COLOR_GEN : READ_DATA;
|
READ_DATA: nextState = (cnt_data >= 3) ? COLOR_GEN : READ_DATA;
|
||||||
COLOR_GEN: nextState = WRITE_DATA;
|
COLOR_GEN: nextState = SEND_DATA;
|
||||||
WRITE_DATA: nextState = SLIDE_WINDOW;
|
SEND_DATA: nextState = (in_receive) ? SLIDE_WINDOW : SEND_DATA;
|
||||||
SLIDE_WINDOW: nextState = READ_DATA;
|
SLIDE_WINDOW: nextState = READ_DATA;
|
||||||
|
default: nextState = 0;
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
|
||||||
|
// 请求数据
|
||||||
|
assign out_ready = (cnt_data <= 2 && !in_en && state == READ_DATA) ? 1 : 0;
|
||||||
|
// 收到数据
|
||||||
|
assign out_receive = (in_en && state == READ_DATA) ? 1 : 0;
|
||||||
|
// 发送数据有效位
|
||||||
|
assign out_en = (in_ready && state == SEND_DATA) ? 1 : 0;
|
||||||
|
|
||||||
// 各状态执行的操作
|
// 各状态执行的操作
|
||||||
always @(posedge clk or posedge reset) begin
|
always @(posedge clk or posedge reset) begin
|
||||||
if (reset) begin
|
if (reset) begin
|
||||||
|
@ -63,32 +73,23 @@ module demosaic2 #(
|
||||||
out_r <= 0;
|
out_r <= 0;
|
||||||
out_g <= 0;
|
out_g <= 0;
|
||||||
out_r <= 0;
|
out_r <= 0;
|
||||||
data_que <= 0;
|
|
||||||
|
|
||||||
// 内部寄存器初始化
|
// 内部寄存器初始化
|
||||||
pos_x <= 0;
|
pos_x <= 0;
|
||||||
pos_y <= 0;
|
pos_y <= 0;
|
||||||
cnt_data <= 0;
|
cnt_data <= 0;
|
||||||
raw_type <= RAW_TYPE;
|
raw_type <= RAW_TYPE;
|
||||||
end
|
end else begin
|
||||||
else begin
|
|
||||||
// 状态机执行
|
// 状态机执行
|
||||||
case (state)
|
case (state)
|
||||||
// 读取数据
|
// 读取数据
|
||||||
READ_DATA: begin
|
READ_DATA: begin
|
||||||
// 请求数据
|
if (in_en) begin
|
||||||
if (cnt_data <= 2) begin
|
data_cache[cnt_data][0] <= in_data[0];
|
||||||
data_que <= 1;
|
data_cache[cnt_data][1] <= in_data[1];
|
||||||
end
|
data_cache[cnt_data][2] <= in_data[2];
|
||||||
|
|
||||||
|
|
||||||
if (data_en) begin
|
|
||||||
data_cache[cnt_data][0] <= data_in[0];
|
|
||||||
data_cache[cnt_data][1] <= data_in[1];
|
|
||||||
data_cache[cnt_data][2] <= data_in[2];
|
|
||||||
|
|
||||||
cnt_data <= cnt_data + 1;
|
cnt_data <= cnt_data + 1;
|
||||||
data_que <= 0;
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -117,11 +118,13 @@ module demosaic2 #(
|
||||||
red <= data_cache[1][1];
|
red <= data_cache[1][1];
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
3: begin // Missing B, R on G
|
3: begin // Missing B, R on G
|
||||||
red <= (data_cache[0][1] + data_cache[2][1]) / 2;
|
red <= (data_cache[0][1] + data_cache[2][1]) / 2;
|
||||||
blue <= (data_cache[1][0] + data_cache[1][2]) / 2;
|
blue <= (data_cache[1][0] + data_cache[1][2]) / 2;
|
||||||
green <= data_cache[1][1];
|
green <= data_cache[1][1];
|
||||||
end
|
end
|
||||||
|
default: ;
|
||||||
endcase
|
endcase
|
||||||
|
|
||||||
case (raw_type)
|
case (raw_type)
|
||||||
|
@ -132,18 +135,15 @@ module demosaic2 #(
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
|
||||||
WRITE_DATA: begin
|
SEND_DATA: begin
|
||||||
out_en <= 1;
|
if (in_ready) begin
|
||||||
out_r <= red;
|
out_r <= red;
|
||||||
out_b <= blue;
|
out_b <= blue;
|
||||||
out_g <= green;
|
out_g <= green;
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
SLIDE_WINDOW: begin
|
SLIDE_WINDOW: begin
|
||||||
// 恢复相关寄存器变量
|
|
||||||
out_en <= 0;
|
|
||||||
|
|
||||||
// 记录位置寄存器自增,并处理缓存数据
|
// 记录位置寄存器自增,并处理缓存数据
|
||||||
pos_x <= pos_x + 1;
|
pos_x <= pos_x + 1;
|
||||||
if (pos_x >= IM_WIDTH - 2 - 1) begin
|
if (pos_x >= IM_WIDTH - 2 - 1) begin
|
||||||
|
@ -156,17 +156,16 @@ module demosaic2 #(
|
||||||
// 换行后切换Bayer格式
|
// 换行后切换Bayer格式
|
||||||
if (pos_y % 2 == 1) begin
|
if (pos_y % 2 == 1) begin
|
||||||
raw_type <= RAW_TYPE;
|
raw_type <= RAW_TYPE;
|
||||||
end
|
end else begin
|
||||||
else begin
|
|
||||||
case (RAW_TYPE)
|
case (RAW_TYPE)
|
||||||
0: raw_type <= 2;
|
0: raw_type <= 2;
|
||||||
1: raw_type <= 3;
|
1: raw_type <= 3;
|
||||||
2: raw_type <= 0;
|
2: raw_type <= 0;
|
||||||
3: raw_type <= 1;
|
3: raw_type <= 1;
|
||||||
|
default: ;
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
end
|
end else begin
|
||||||
else begin
|
|
||||||
cnt_data <= 2;
|
cnt_data <= 2;
|
||||||
|
|
||||||
// 窗口右移
|
// 窗口右移
|
||||||
|
@ -178,6 +177,8 @@ module demosaic2 #(
|
||||||
data_cache[1][2] <= data_cache[2][2];
|
data_cache[1][2] <= data_cache[2][2];
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
default: ;
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
894
FIFO/SOFTFIFO.v
894
FIFO/SOFTFIFO.v
|
@ -1,894 +0,0 @@
|
||||||
|
|
||||||
`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,116 +0,0 @@
|
||||||
`timescale 1ns/1ps
|
|
||||||
|
|
||||||
// 三通道图像合成一个RGB图像
|
|
||||||
module chanels_to_RGB #(
|
|
||||||
parameter IN_DEPTH = 12, // 输入图像的色深
|
|
||||||
parameter OUT_DEPTH = 8, // 输出图像的色深
|
|
||||||
parameter GAIN_RED = 120, // 红色增益系数(除以10^小数位数)
|
|
||||||
parameter GAIN_GREEN = 50, // 绿色增益系数
|
|
||||||
parameter GAIN_BLUE = 95, // 蓝色增益系数
|
|
||||||
parameter DECIMAL = 2 // 小数位数
|
|
||||||
) (
|
|
||||||
input clk,
|
|
||||||
input reset,
|
|
||||||
|
|
||||||
input in_en,
|
|
||||||
input [15:0] data_in [2:0], // 0:R 1:G 2:B
|
|
||||||
|
|
||||||
// 输出相关
|
|
||||||
input out_que, // 数据请求
|
|
||||||
output out_en,
|
|
||||||
output [3 * OUT_DEPTH - 1:0] data_out,
|
|
||||||
|
|
||||||
// 颜色校正
|
|
||||||
input wire color_correction
|
|
||||||
);
|
|
||||||
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, 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
|
|
||||||
// 初始化
|
|
||||||
data_cal[0] <= 0;
|
|
||||||
data_cal[1] <= 0;
|
|
||||||
data_cal[2] <= 0;
|
|
||||||
fifo_en <= 0;
|
|
||||||
fifo_in <= 0;
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
case (state)
|
|
||||||
READ_DATA: begin
|
|
||||||
fifo_en <= 0;
|
|
||||||
|
|
||||||
if (in_en) begin
|
|
||||||
if (color_correction) begin
|
|
||||||
data_cal[0] <= ( {16'b0, data_in[0] } >> (IN_DEPTH - OUT_DEPTH) ) * GAIN_RED / (10 ** DECIMAL);
|
|
||||||
data_cal[1] <= ( {16'b0, data_in[1] } >> (IN_DEPTH - OUT_DEPTH) ) * GAIN_GREEN / (10 ** DECIMAL);
|
|
||||||
data_cal[2] <= ( {16'b0, data_in[2] } >> (IN_DEPTH - OUT_DEPTH) ) * GAIN_BLUE / (10 ** DECIMAL);
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
data_cal[0] <= ( {16'b0, data_in[0] } >> (IN_DEPTH - OUT_DEPTH) );
|
|
||||||
data_cal[1] <= ( {16'b0, data_in[1] } >> (IN_DEPTH - OUT_DEPTH) );
|
|
||||||
data_cal[2] <= ( {16'b0, data_in[2] } >> (IN_DEPTH - OUT_DEPTH) );
|
|
||||||
end
|
|
||||||
|
|
||||||
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 fifo_que = (out_que && !fifo_empty) ? 1 : 0;
|
|
||||||
|
|
||||||
SOFTFIFO #(
|
|
||||||
.DATA_WIDTH_W(3 * OUT_DEPTH),
|
|
||||||
.DATA_WIDTH_R(3 * OUT_DEPTH)
|
|
||||||
) RGB_FIFO (
|
|
||||||
.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
|
|
7
isp.v
7
isp.v
|
@ -39,8 +39,7 @@ module isp #(
|
||||||
// wire RAM_in_que; // RAM 请求数据
|
// wire RAM_in_que; // RAM 请求数据
|
||||||
// wire [3 * COLOR_DEPTH - 1:0] RAM_in_data;
|
// wire [3 * COLOR_DEPTH - 1:0] RAM_in_data;
|
||||||
|
|
||||||
always @(clk)
|
always @(clk) out_clk <= clk;
|
||||||
out_clk <= clk;
|
|
||||||
|
|
||||||
demosaic2 #(
|
demosaic2 #(
|
||||||
.IM_WIDTH (IN_WIDTH),
|
.IM_WIDTH (IN_WIDTH),
|
||||||
|
@ -58,7 +57,7 @@ module isp #(
|
||||||
.out_b(im_blue)
|
.out_b(im_blue)
|
||||||
);
|
);
|
||||||
|
|
||||||
chanels_to_RGB #(
|
ColorBlender #(
|
||||||
.IN_DEPTH (12),
|
.IN_DEPTH (12),
|
||||||
.OUT_DEPTH(8),
|
.OUT_DEPTH(8),
|
||||||
|
|
||||||
|
@ -66,7 +65,7 @@ module isp #(
|
||||||
.GAIN_GREEN(50),
|
.GAIN_GREEN(50),
|
||||||
.GAIN_BLUE(95),
|
.GAIN_BLUE(95),
|
||||||
.DECIMAL(2)
|
.DECIMAL(2)
|
||||||
) merge_toRGB(
|
) blender (
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
.reset(reset),
|
.reset(reset),
|
||||||
.in_en(rgb_en),
|
.in_en(rgb_en),
|
||||||
|
|
|
@ -205,7 +205,7 @@ int sc_main(int argc, char* argv[]) {
|
||||||
isp->data_out(data_out);
|
isp->data_out(data_out);
|
||||||
isp->color_correction(color_correction);
|
isp->color_correction(color_correction);
|
||||||
|
|
||||||
color_correction.write(true); // enable color correction
|
color_correction.write(false); // enable color correction
|
||||||
|
|
||||||
// Construct testbench module
|
// Construct testbench module
|
||||||
TB_ISP tb_isp("tb_isp");
|
TB_ISP tb_isp("tb_isp");
|
||||||
|
|
Loading…
Reference in New Issue