Anndy. 2024-04-22 12:18 采纳率: 0%
浏览 9
已结题

Verilog做卷积的问题

verilog里做卷积,这样的代码有问题吗?
最后得到的结果conv_res的每一位都是固定的3,而且padding部分也都得到错误的结果。
问题应该是处在always与for的循环里,这种采用<=赋值的方法难道不会在每次for循环迭代时都进行一次运算吗?


integer k,p;
initial begin
    for(k=0; k!=DATA_WIDTH ; k=k+1) begin
        for(p=0; p!=DATA_WIDTH ; p=p+1)
            data_in[k][p] = 1;
    end
end


initial begin
    for(k=0; k!=KERNEL_WIDTH ; k=k+1) begin
        for(p=0; p!=KERNEL_WIDTH ; p=p+1)
            kernel[k][p] = 3;
    end
end

initial begin
    for(k=0; k!=(PADDING_SIZE+DATA_WIDTH) ; k=k+1) begin
        for(p=0; p!=(PADDING_SIZE+DATA_WIDTH) ; p=p+1)
            conv_res[k][p] = 0;
    end
end

initial begin
    for(k=0; k!=(PADDING_SIZE+DATA_WIDTH) ; k=k+1) begin
        for(p=0; p!=(PADDING_SIZE+DATA_WIDTH) ; p=p+1)
            padded_input[k][p] = 0;
    end
end
reg     init_begin;
//数据padding填充
integer i_1, j_1;
always@(posedge clk) begin
    if(init_begin) begin
        for (i_1 = 0; i_1 < (PADDING_SIZE + DATA_WIDTH); i_1 = i_1 + 1) begin 
            for(j_1 = 0; j_1 < (PADDING_SIZE + DATA_WIDTH); j_1 = j_1 + 1) begin
                if(((i_1 >= DATA_WIDTH) && (i_1 < (PADDING_SIZE + DATA_WIDTH))) || ((j_1 >= DATA_WIDTH) && (j_1 < (PADDING_SIZE + DATA_WIDTH)))) begin
                    padded_input[i_1][j_1] <= 32'b0;
                end
                else begin
                    padded_input[i_1][j_1] <= data_in[i_1][j_1];
                end
            end
        end
    end
end
//卷积运算
always @(posedge clk) begin
    for (j = 0; j < DATA_WIDTH; j = j + 1) begin
        for(m = 0; m < KERNEL_WIDTH; m = m + 1) begin
            for(n = 0; n < KERNEL_WIDTH; n = n + 1) begin
                conv_res[i][j] <= conv_res[i][j] + padded_input[i+m][j+n] * kernel[m][n];
            end
        end      
    end
end
  • 写回答

4条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-04-22 12:18
    关注

    引自免费微信小程序:皆我百晓生

    根据您提供的代码,存在几个潜在的问题。首先,您没有定义clk信号,这可能是同步时序逻辑的触发器。其次,您没有为init_begin变量设置初始值或改变它的状态,这可能导致初始化阶段的逻辑不正确。再次,您的卷积计算可能有误,因为它可能会对输出矩阵的同一位置进行多次累加。下面是对这些问题的修改建议:

    1. 定义clk信号:
    input wire clk;
    
    1. 设置init_begin的初始值:
    reg init_begin = 1'b0;
    
    1. 在适当的地方将init_begin设为低,以便结束初始化:
    always @(posedge clk) begin
        if (!reset) begin
            init_begin <= 1'b0;
        end else if (!init_begin) begin
            // 卷积运算部分保持不变
        end
    end
    
    1. 对于卷积运算,确保您仅对每个输出元素执行一次累加操作。可以使用一个额外的条件检查来实现这一点,例如跟踪当前的输出位置。这里是一个示例,展示了如何使用一个临时变量current_output_pos来记录当前正在处理的输出位置,并且在遍历输入矩阵时更新它:
    reg [DATA_WIDTH-1:0] current_output_pos;
    
    always @(posedge clk) begin
        if (!reset) begin
            init_begin <= 1'b0;
            current_output_pos <= 0;
        end else if (!init_begin) begin
            // 初始化部分保持不变
        end else begin
            // 更新当前输出位置
            current_output_pos <= current_output_pos + 1;
    
            // 检查是否已经处理过当前位置
            reg has_processed = 1'b0;
            if (current_output_pos < (PADDING_SIZE + DATA_WIDTH - KERNEL_WIDTH + 1)) begin
                has_processed <= 1'b1;
            end
    
            if (!has_processed) begin
                for (m = 0; m < KERNEL_WIDTH; m = m + 1) begin
                    for(n = 0; n < KERNEL_WIDTH; n = n + 1) begin
                        conv_res[current_output_pos][j] <= conv_res[current_output_pos][j] + padded_input[current_output_pos+m][j+n] * kernel[m][n];
                    end
                end
                conv_res[(current_output_pos + KERNEL_WIDTH - 1)[DATA_WIDTH-1]:0] <= conv_res[current_output_pos][j]; // 这一行是为了防止溢出
            end
        end
    end
    

    请注意,这个修正版本的代码仅作为参考,实际应用中可能还需要根据具体需求进行调整。例如,您可能需要添加边界条件检查以确保不会访问超出数组范围的位置,以及考虑reset信号用于重置整个模块的状态等。此外,为了简化问题,这里的代码没有包含宽度和高度的边界检查,实际实现中应确保这些检查。

    评论 编辑记录

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 4月22日
  • 创建了问题 4月22日

悬赏问题

  • ¥15 用C语言怎么判断字符串的输入是否符合设定?
  • ¥15 通信专业本科生论文选这两个哪个方向好研究呀
  • ¥50 我在一个购物网站的排队系统排队,这个排队到号后重新定向到目标网站进行购物,但是有技术牛通过技术方法直接跳过排队系统进入目标网址购物,有没有什么软件或者脚本可以用
  • ¥15 ios可以实现ymodem-1k协议 1024字节传输吗?
  • ¥300 寻抓云闪付tn组成网页付款链接
  • ¥15 请问Ubuntu要怎么安装chrome呀?
  • ¥15 视频编码 十六进制问题
  • ¥15 unity terrain打包后地形错位,跟建筑不在同一个位置,怎么办
  • ¥15 uniapp实现如下图的图表功能
  • ¥15 u-subsection如何修改相邻两个节点样式