在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 2888|回复: 4

[求助] Verilog中求绝对值的一点困惑

[复制链接]
发表于 2023-3-7 17:51:44 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
按照一般理解,Verilog中求绝对值时涉及到负数计算,需要把该变量声明为signed类型,通过判断最高位是0或1来进行分类谈论计算,但是在野火FPGA教程中的写法让我产生了疑惑,他并没有将gx或gy声明成signed类型,但是最后却能通过判断最高位来进行分类讨论计算。最后功能是正常的,这是为什么呢?难道编译器会自动判断结果是正数还是负数吗?正数就存储原码,负数就存补码,最后可以判断?求各位懂的解释一下,感谢!

                               
登录/注册后可看大图

                               
登录/注册后可看大图

发表于 2023-3-8 15:34:31 | 显示全部楼层
这个问题,其实跟verilog关系不大,你需要再去翻翻数字电路的基础教材,或者是计算机原理的基础教材,去理解补码的来龙去脉,补码是一个文字游戏,是人们为了利用最简单的二进制全加器电路,实现二进制加减法,通过重新定义一个最简电路的运算结果,以最小的代价实现更多的功能,比如,我们要计算0 - 1,加入我们就用两比特来表示操作数,就是 0b00 - 0b01 = 0b11,咋办,结果错了,但如果你按补码去解读结果数据,巧了,0b11就是-1;但是,我们现在只有加法器,前面用的是减法器,咋办?好,我们把- 1改写成 + (-1)呢,-1,用两比特表示的补码是0b11,然后,我们来计算 0b00 + 0b11 = 0b11,结果是-1,还是那么巧,结果正确,如果要计算 1 - 1呢,计算 1 + (-1),就是0b01 + 0b11 = 0b00,结果就是0。所以,通过补码的定义,人们发现,只要在原来的二进制全加器的基础上,增加一个sub信号,将这个信号作为此全加器的进位输入,同时在全加器的其中一个操作数的前端,利用此信号控制一个反相器的选择,从而可以实现在电路端将正/负、加/减统一起来。建议你去翻教材,毕竟教材图文并茂,比我讲的更生动,更容易理解。


至于你说的程序运行结果是对的,这倒不一定,因为你给出的代码片段可能有问题:第一种条件(即gx,gy都为负数时),如果都是-128,因为gxy定义为8bits的,这个地方计算会出错,会溢出,导致gxy的结果会变为0,我不知道你这个程序的原理是不是保证了gx,gy不会同时为-128,所以我不确定你这个电路是不是真的不会出错。
发表于 2023-3-9 18:45:28 | 显示全部楼层
本帖最后由 Love24 于 2023-3-9 18:47 编辑

你可以看下它的图像是如何存储的,很显然,这里的计算方式说明了gx,gy是以补码形式存放的,或者说gx,gy带有了符号信息,定义reg时一般都说它是无符号数,但是reg的本质是一串二进制序列,所以根源还是看原始数据是如何存储的;
 楼主| 发表于 2023-3-9 22:06:24 | 显示全部楼层


Love24 发表于 2023-3-9 18:45
你可以看下它的图像是如何存储的,很显然,这里的计算方式说明了gx,gy是以补码形式存放的,或者说gx,gy带 ...



`timescale  1ns/1ns
////////////////////////////////////////////////////////////////////////
// Author        : EmbedFire
// Create Date   : 2019/03/18
// Module Name   : sobel_ctrl
// Project Name  : sobel
// Target Devices: Altera EP4CE10F17C8N
// Tool Versions : Quartus 13.0
// Description   : 数据求和模块
//
// Revision      : V1.0
// Additional Comments:
//
// 实验平台: 野火_征途Pro_FPGA开发板
// 公司    : http://www.embedfire.com
// 论坛    : http://www.firebbs.cn
// 淘宝    : https://fire-stm32.taobao.com
////////////////////////////////////////////////////////////////////////

module  sobel_ctrl
(
    input   wire            sys_clk     ,   //输入系统时钟,频率50MHz
    input   wire            sys_rst_n   ,   //复位信号,低有效
    input   wire    [7:0]   pi_data     ,   //rx传入的数据信号
    input   wire            pi_flag     ,   //rx传入的标志信号

    output  reg     [7:0]   po_data     ,   //fifo加法运算后的信号
    output  reg             po_flag         //输出标志信号
);

//********************************************************************//
//****************** Parameter and Internal Signal *******************//
//********************************************************************//
//parameter define
parameter   LENGTH_P    =   10'd100         ,   //图片长度
            WIDE_P      =   10'd100         ;   //图片宽度
parameter   THRESHOLD   =   8'b000_011_00   ;   //比较阈值
parameter   BLACK       =   8'b0000_0000    ,   //黑色
            WHITE       =   8'b1111_1111    ;   //白色

//wire  define
wire    [7:0]   data_out1   ;   //fifo1数据输出
wire    [7:0]   data_out2   ;   //fifo2数据输出

//reg   define
reg     [7:0]   cnt_h       ;   //行计数
reg     [7:0]   cnt_v       ;   //场计数
reg     [7:0]   pi_data_dly ;   //pi_data数据寄存
reg             wr_en1      ;   //fifo1写使能
reg             wr_en2      ;   //fifo2写使能
reg     [7:0]   data_in1    ;   //fifo1写数据
reg     [7:0]   data_in2    ;   //fifo2写数据
reg             rd_en       ;   //fifo1,fifo2共用读使能
reg     [7:0]   data_out1_dly   ;   //fifo1数据输出寄存
reg     [7:0]   data_out2_dly   ;   //fifo2数据输出寄存
reg             dout_flag   ;   //使能信号
reg             rd_en_dly1  ;   //输出数据标志信号,延后rd_en一拍
reg             rd_en_dly2  ;   //a,b,c赋值标志信号
reg             gx_gy_flag  ;   //gx,gy计算标志信号
reg             gxy_flag    ;   //gxy计算标志信号
reg             compare_flag;   //阈值比较标志信号
reg     [7:0]   cnt_rd      ;   //读出数据计数器
reg     [7:0]   a1          ;
reg     [7:0]   a2          ;
reg     [7:0]   a3          ;
reg     [7:0]   b1          ;
reg     [7:0]   b2          ;
reg     [7:0]   b3          ;
reg     [7:0]   c1          ;
reg     [7:0]   c2          ;
reg     [7:0]   c3          ;   //图像数据
reg     [8:0]   gx          ;
reg     [8:0]   gy          ;   //gx,gy
reg     [7:0]   gxy         ;   //gxy

//********************************************************************//
//***************************** Main Code ****************************//
//********************************************************************//
//cnt_h:行数据个数计数器
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_h   <=  8'd0;
    else    if((cnt_h == (LENGTH_P - 1'b1)) && (pi_flag == 1'b1))
        cnt_h   <=  8'd0;
    else    if(pi_flag == 1'b1)
        cnt_h   <=  cnt_h + 1'b1;

//cnt_v:场计数器
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_v   <=  8'd0;
    else    if((cnt_v == (WIDE_P - 1'b1)) && (pi_flag == 1'b1)
            && (cnt_h == (LENGTH_P - 1'b1)))
        cnt_v   <=  8'd0;
    else    if((cnt_h == (LENGTH_P - 1'b1)) && (pi_flag == 1'b1))
        cnt_v   <=  cnt_v + 1'b1;

//cnt_rd:fifo数据读出个数计数,用来判断何时对gx,gy进行运算
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_rd   <=  8'd0;
    else    if((cnt_rd == (LENGTH_P - 1'b1)) && (rd_en == 1'b1))
        cnt_rd   <=  8'd0;
    else    if(rd_en == 1'b1)
        cnt_rd   <=  cnt_rd + 1'b1;

//wr_en1:fifo1写使能,高电平有效
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        wr_en1  <=  1'b0;
    else    if((cnt_v == 8'd0) && (pi_flag == 1'b1))
        wr_en1  <=  1'b1;      //第0行写入fifo1
    else
        wr_en1  <=  dout_flag;  //2-198行写入fifo1

//wr_en2,fifo2的写使能,高电平有效
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        wr_en2  <=  1'b0;
    else    if((cnt_v >= 8'd1)&&(cnt_v <= ((WIDE_P - 1'b1) - 1'b1))
            && (pi_flag == 1'b1))
        wr_en2  <=  1'b1;      //2-199行写入fifo2
    else
        wr_en2  <=  1'b0;

//data_in1:fifo1的数据写入
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        data_in1    <=  8'b0;
    else    if((pi_flag == 1'b1) && (cnt_v == 8'b0))
        data_in1    <=  pi_data;
    else    if(dout_flag == 1'b1)
        data_in1    <=  data_out2;
    else
        data_in1    <=  data_in1;

//data_in2:fifo2的数据写入
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        data_in2    <=  8'b0;
    else    if((pi_flag == 1'b1) && (cnt_v >= 8'd1)
            && (cnt_v <= ((WIDE_P - 1'b1) - 1'b1)))
        data_in2    <=  pi_data;
    else
        data_in2    <=  data_in2;

//rd_en:fifo1和fifo2的共用读使能,高电平有效
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        rd_en   <=  1'b0;
    else    if((pi_flag == 1'b1) && (cnt_v >= 8'd2)
            && (cnt_v <= (WIDE_P - 1'b1)))
        rd_en   <=  1'b1;  
    else
        rd_en   <=  1'b0;


//dout_flag:控制fifo1写使能wr_en1
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        dout_flag   <=  1'b0;
    else    if((wr_en2 == 1'b1) && (rd_en == 1'b1))
        dout_flag   <=  1'b1;
    else
        dout_flag   <=  1'b0;

//rd_en_dly1:输出数据标志信号
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        rd_en_dly1  <=  1'b0;
    else    if(rd_en == 1'b1)
        rd_en_dly1  <=  1'b1;
    else
        rd_en_dly1  <=  1'b0;

//data_out1_dly:data_out1数据寄存
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        data_out1_dly   <=  8'b0;
    else    if(rd_en_dly1 == 1'b1)
        data_out1_dly   <=  data_out1;

//data_out2_dly:data_out2数据寄存
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        data_out2_dly   <=  8'b0;
    else    if(rd_en_dly1 == 1'b1)
        data_out2_dly   <=  data_out2;

//pi_data_dly:输入数据pi_data寄存
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        pi_data_dly <=  8'b0;
    else    if(rd_en_dly1 == 1'b1)
        pi_data_dly <=  pi_data;

//rd_en_dly2:a,b,c赋值标志信号
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        rd_en_dly2  <=  1'b0;
    else    if(rd_en_dly1 == 1'b1)
        rd_en_dly2  <=  1'b1;
    else
        rd_en_dly2  <=  1'b0;

//gx_gy_flag:gx,gy计算标志信号
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        gx_gy_flag  <=  1'b0;
    else    if((rd_en_dly2 == 1'b1) && ((cnt_rd >= 8'd3) || (cnt_rd == 8'd0)))
        gx_gy_flag  <=  1'b1;
    else
        gx_gy_flag  <=  1'b0;

//gxy_flag:gxy计算标准信号
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        gxy_flag    <=  1'b0;
    else    if(gx_gy_flag == 1'b1)
        gxy_flag    <=  1'b1;
    else
        gxy_flag    <=  1'b0;

//compare_flag,阈值比较标志信号
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        compare_flag    <=  1'b0;
    else    if(gxy_flag == 1'b1)
        compare_flag    <=  1'b1;
    else
        compare_flag    <=  1'b0;

//a,b,c赋值
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
    begin
        a1  <=  8'd0;
        a2  <=  8'd0;
        a3  <=  8'd0;
        b1  <=  8'd0;
        b2  <=  8'd0;
        b3  <=  8'd0;
        c1  <=  8'd0;
        c2  <=  8'd0;
        c3  <=  8'd0;
    end
    else    if(rd_en_dly2==1)
    begin
        a1  <=  data_out1_dly;
        b1  <=  data_out2_dly;
        c1  <=  pi_data_dly;
        a2  <=  a1;
        b2  <=  b1;
        c2  <=  c1;
        a3  <=  a2;
        b3  <=  b2;
        c3  <=  c2;
    end

//gx:计算gx
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        gx  <=  9'd0;
    else    if(gx_gy_flag == 1'b1)
        gx  <=  a3 - a1 + ((b3 - b1) << 1) + c3 - c1;
    else
        gx  <=  gx;

//gy:计算gy
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        gy  <=  9'd0;
    else    if(gx_gy_flag == 1'b1)
        gy  <=  a1 - c1 + ((a2 - c2) << 1) + a3 - c3;
    else
        gy  <=  gy;

//gxy:gxy计算
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        gxy <=  0;
    else    if((gx[8] == 1'b1) && (gy[8] == 1'b1) && (gxy_flag == 1'b1))
        gxy <=  (~gx[7:0] + 1'b1) + (~gy[7:0] + 1'b1);
    else    if((gx[8] == 1'b1) && (gy[8] == 1'b0) && (gxy_flag == 1'b1))
        gxy <=  (~gx[7:0] + 1'b1) + (gy[7:0]);
    else    if((gx[8] == 1'b0) && (gy[8] == 1'b1) && (gxy_flag == 1'b1))
        gxy <=  (gx[7:0]) + (~gy[7:0] + 1'b1);
    else    if((gx[8] == 1'b0) && (gy[8] == 1'b0) && (gxy_flag == 1'b1))
        gxy <=  (gx[7:0]) + (gy[7:0]);

//po_data:通过gxy与阈值比较,赋值po_data
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        po_data <=  8'b0;
    else    if((gxy >= THRESHOLD) && (compare_flag == 1'b1))
        po_data <=  BLACK;
    else    if(compare_flag == 1'b1)
        po_data <=  WHITE;

//po_flag:输出标志位
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        po_flag <=  1'b0;
    else    if(compare_flag == 1'b1)
        po_flag <=  1'b1;
    else
        po_flag <=  1'b0;

//********************************************************************//
//*************************** Instantiation **************************//
//********************************************************************//
//-------------fifo_pic_inst1--------------
fifo_pic    fifo_pic_inst1
(
    .clock  (sys_clk    ),  // input sys_clk
    .data   (data_in1   ),  // input [7 : 0] din
    .wrreq  (wr_en1     ),  // input wr_en
    .rdreq  (rd_en      ),  // input rd_en

    .q      (data_out1  )   // output [7 : 0] dout
);

//-------------fifo_pic_inst2--------------
fifo_pic    fifo_pic_inst2
(
    .clock  (sys_clk    ),  // input sys_clk
    .data   (data_in2   ),  // input [7 : 0] din
    .wrreq  (wr_en2     ),  // input wr_en
    .rdreq  (rd_en      ),  // input rd_en

    .q      (data_out2  )   // output [7 : 0] dout
);

endmodule


 楼主| 发表于 2023-3-9 22:07:14 | 显示全部楼层


innovation 发表于 2023-3-8 15:34
这个问题,其实跟verilog关系不大,你需要再去翻翻数字电路的基础教材,或者是计算机原理的基础教材,去理 ...



`timescale  1ns/1ns
////////////////////////////////////////////////////////////////////////
// Author        : EmbedFire
// Create Date   : 2019/03/18
// Module Name   : sobel_ctrl
// Project Name  : sobel
// Target Devices: Altera EP4CE10F17C8N
// Tool Versions : Quartus 13.0
// Description   : 数据求和模块
//
// Revision      : V1.0
// Additional Comments:
//
// 实验平台: 野火_征途Pro_FPGA开发板
// 公司    : http://www.embedfire.com
// 论坛    : http://www.firebbs.cn
// 淘宝    : https://fire-stm32.taobao.com
////////////////////////////////////////////////////////////////////////

module  sobel_ctrl
(
    input   wire            sys_clk     ,   //输入系统时钟,频率50MHz
    input   wire            sys_rst_n   ,   //复位信号,低有效
    input   wire    [7:0]   pi_data     ,   //rx传入的数据信号
    input   wire            pi_flag     ,   //rx传入的标志信号

    output  reg     [7:0]   po_data     ,   //fifo加法运算后的信号
    output  reg             po_flag         //输出标志信号
);

//********************************************************************//
//****************** Parameter and Internal Signal *******************//
//********************************************************************//
//parameter define
parameter   LENGTH_P    =   10'd100         ,   //图片长度
            WIDE_P      =   10'd100         ;   //图片宽度
parameter   THRESHOLD   =   8'b000_011_00   ;   //比较阈值
parameter   BLACK       =   8'b0000_0000    ,   //黑色
            WHITE       =   8'b1111_1111    ;   //白色

//wire  define
wire    [7:0]   data_out1   ;   //fifo1数据输出
wire    [7:0]   data_out2   ;   //fifo2数据输出

//reg   define
reg     [7:0]   cnt_h       ;   //行计数
reg     [7:0]   cnt_v       ;   //场计数
reg     [7:0]   pi_data_dly ;   //pi_data数据寄存
reg             wr_en1      ;   //fifo1写使能
reg             wr_en2      ;   //fifo2写使能
reg     [7:0]   data_in1    ;   //fifo1写数据
reg     [7:0]   data_in2    ;   //fifo2写数据
reg             rd_en       ;   //fifo1,fifo2共用读使能
reg     [7:0]   data_out1_dly   ;   //fifo1数据输出寄存
reg     [7:0]   data_out2_dly   ;   //fifo2数据输出寄存
reg             dout_flag   ;   //使能信号
reg             rd_en_dly1  ;   //输出数据标志信号,延后rd_en一拍
reg             rd_en_dly2  ;   //a,b,c赋值标志信号
reg             gx_gy_flag  ;   //gx,gy计算标志信号
reg             gxy_flag    ;   //gxy计算标志信号
reg             compare_flag;   //阈值比较标志信号
reg     [7:0]   cnt_rd      ;   //读出数据计数器
reg     [7:0]   a1          ;
reg     [7:0]   a2          ;
reg     [7:0]   a3          ;
reg     [7:0]   b1          ;
reg     [7:0]   b2          ;
reg     [7:0]   b3          ;
reg     [7:0]   c1          ;
reg     [7:0]   c2          ;
reg     [7:0]   c3          ;   //图像数据
reg     [8:0]   gx          ;
reg     [8:0]   gy          ;   //gx,gy
reg     [7:0]   gxy         ;   //gxy

//********************************************************************//
//***************************** Main Code ****************************//
//********************************************************************//
//cnt_h:行数据个数计数器
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_h   <=  8'd0;
    else    if((cnt_h == (LENGTH_P - 1'b1)) && (pi_flag == 1'b1))
        cnt_h   <=  8'd0;
    else    if(pi_flag == 1'b1)
        cnt_h   <=  cnt_h + 1'b1;

//cnt_v:场计数器
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_v   <=  8'd0;
    else    if((cnt_v == (WIDE_P - 1'b1)) && (pi_flag == 1'b1)
            && (cnt_h == (LENGTH_P - 1'b1)))
        cnt_v   <=  8'd0;
    else    if((cnt_h == (LENGTH_P - 1'b1)) && (pi_flag == 1'b1))
        cnt_v   <=  cnt_v + 1'b1;

//cnt_rd:fifo数据读出个数计数,用来判断何时对gx,gy进行运算
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_rd   <=  8'd0;
    else    if((cnt_rd == (LENGTH_P - 1'b1)) && (rd_en == 1'b1))
        cnt_rd   <=  8'd0;
    else    if(rd_en == 1'b1)
        cnt_rd   <=  cnt_rd + 1'b1;

//wr_en1:fifo1写使能,高电平有效
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        wr_en1  <=  1'b0;
    else    if((cnt_v == 8'd0) && (pi_flag == 1'b1))
        wr_en1  <=  1'b1;      //第0行写入fifo1
    else
        wr_en1  <=  dout_flag;  //2-198行写入fifo1

//wr_en2,fifo2的写使能,高电平有效
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        wr_en2  <=  1'b0;
    else    if((cnt_v >= 8'd1)&&(cnt_v <= ((WIDE_P - 1'b1) - 1'b1))
            && (pi_flag == 1'b1))
        wr_en2  <=  1'b1;      //2-199行写入fifo2
    else
        wr_en2  <=  1'b0;

//data_in1:fifo1的数据写入
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        data_in1    <=  8'b0;
    else    if((pi_flag == 1'b1) && (cnt_v == 8'b0))
        data_in1    <=  pi_data;
    else    if(dout_flag == 1'b1)
        data_in1    <=  data_out2;
    else
        data_in1    <=  data_in1;

//data_in2:fifo2的数据写入
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        data_in2    <=  8'b0;
    else    if((pi_flag == 1'b1) && (cnt_v >= 8'd1)
            && (cnt_v <= ((WIDE_P - 1'b1) - 1'b1)))
        data_in2    <=  pi_data;
    else
        data_in2    <=  data_in2;

//rd_en:fifo1和fifo2的共用读使能,高电平有效
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        rd_en   <=  1'b0;
    else    if((pi_flag == 1'b1) && (cnt_v >= 8'd2)
            && (cnt_v <= (WIDE_P - 1'b1)))
        rd_en   <=  1'b1;  
    else
        rd_en   <=  1'b0;


//dout_flag:控制fifo1写使能wr_en1
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        dout_flag   <=  1'b0;
    else    if((wr_en2 == 1'b1) && (rd_en == 1'b1))
        dout_flag   <=  1'b1;
    else
        dout_flag   <=  1'b0;

//rd_en_dly1:输出数据标志信号
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        rd_en_dly1  <=  1'b0;
    else    if(rd_en == 1'b1)
        rd_en_dly1  <=  1'b1;
    else
        rd_en_dly1  <=  1'b0;

//data_out1_dly:data_out1数据寄存
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        data_out1_dly   <=  8'b0;
    else    if(rd_en_dly1 == 1'b1)
        data_out1_dly   <=  data_out1;

//data_out2_dly:data_out2数据寄存
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        data_out2_dly   <=  8'b0;
    else    if(rd_en_dly1 == 1'b1)
        data_out2_dly   <=  data_out2;

//pi_data_dly:输入数据pi_data寄存
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        pi_data_dly <=  8'b0;
    else    if(rd_en_dly1 == 1'b1)
        pi_data_dly <=  pi_data;

//rd_en_dly2:a,b,c赋值标志信号
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        rd_en_dly2  <=  1'b0;
    else    if(rd_en_dly1 == 1'b1)
        rd_en_dly2  <=  1'b1;
    else
        rd_en_dly2  <=  1'b0;

//gx_gy_flag:gx,gy计算标志信号
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        gx_gy_flag  <=  1'b0;
    else    if((rd_en_dly2 == 1'b1) && ((cnt_rd >= 8'd3) || (cnt_rd == 8'd0)))
        gx_gy_flag  <=  1'b1;
    else
        gx_gy_flag  <=  1'b0;

//gxy_flag:gxy计算标准信号
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        gxy_flag    <=  1'b0;
    else    if(gx_gy_flag == 1'b1)
        gxy_flag    <=  1'b1;
    else
        gxy_flag    <=  1'b0;

//compare_flag,阈值比较标志信号
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        compare_flag    <=  1'b0;
    else    if(gxy_flag == 1'b1)
        compare_flag    <=  1'b1;
    else
        compare_flag    <=  1'b0;

//a,b,c赋值
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
    begin
        a1  <=  8'd0;
        a2  <=  8'd0;
        a3  <=  8'd0;
        b1  <=  8'd0;
        b2  <=  8'd0;
        b3  <=  8'd0;
        c1  <=  8'd0;
        c2  <=  8'd0;
        c3  <=  8'd0;
    end
    else    if(rd_en_dly2==1)
    begin
        a1  <=  data_out1_dly;
        b1  <=  data_out2_dly;
        c1  <=  pi_data_dly;
        a2  <=  a1;
        b2  <=  b1;
        c2  <=  c1;
        a3  <=  a2;
        b3  <=  b2;
        c3  <=  c2;
    end

//gx:计算gx
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        gx  <=  9'd0;
    else    if(gx_gy_flag == 1'b1)
        gx  <=  a3 - a1 + ((b3 - b1) << 1) + c3 - c1;
    else
        gx  <=  gx;

//gy:计算gy
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        gy  <=  9'd0;
    else    if(gx_gy_flag == 1'b1)
        gy  <=  a1 - c1 + ((a2 - c2) << 1) + a3 - c3;
    else
        gy  <=  gy;

//gxy:gxy计算
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        gxy <=  0;
    else    if((gx[8] == 1'b1) && (gy[8] == 1'b1) && (gxy_flag == 1'b1))
        gxy <=  (~gx[7:0] + 1'b1) + (~gy[7:0] + 1'b1);
    else    if((gx[8] == 1'b1) && (gy[8] == 1'b0) && (gxy_flag == 1'b1))
        gxy <=  (~gx[7:0] + 1'b1) + (gy[7:0]);
    else    if((gx[8] == 1'b0) && (gy[8] == 1'b1) && (gxy_flag == 1'b1))
        gxy <=  (gx[7:0]) + (~gy[7:0] + 1'b1);
    else    if((gx[8] == 1'b0) && (gy[8] == 1'b0) && (gxy_flag == 1'b1))
        gxy <=  (gx[7:0]) + (gy[7:0]);

//po_data:通过gxy与阈值比较,赋值po_data
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        po_data <=  8'b0;
    else    if((gxy >= THRESHOLD) && (compare_flag == 1'b1))
        po_data <=  BLACK;
    else    if(compare_flag == 1'b1)
        po_data <=  WHITE;

//po_flag:输出标志位
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        po_flag <=  1'b0;
    else    if(compare_flag == 1'b1)
        po_flag <=  1'b1;
    else
        po_flag <=  1'b0;

//********************************************************************//
//*************************** Instantiation **************************//
//********************************************************************//
//-------------fifo_pic_inst1--------------
fifo_pic    fifo_pic_inst1
(
    .clock  (sys_clk    ),  // input sys_clk
    .data   (data_in1   ),  // input [7 : 0] din
    .wrreq  (wr_en1     ),  // input wr_en
    .rdreq  (rd_en      ),  // input rd_en

    .q      (data_out1  )   // output [7 : 0] dout
);

//-------------fifo_pic_inst2--------------
fifo_pic    fifo_pic_inst2
(
    .clock  (sys_clk    ),  // input sys_clk
    .data   (data_in2   ),  // input [7 : 0] din
    .wrreq  (wr_en2     ),  // input wr_en
    .rdreq  (rd_en      ),  // input rd_en

    .q      (data_out2  )   // output [7 : 0] dout
);

endmodule



您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /1 下一条

小黑屋| 手机版| 关于我们| 联系我们| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2025-5-16 07:21 , Processed in 0.033436 second(s), 9 queries , Gzip On, MemCached On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表