芯路恒电子技术论坛

 找回密码
 立即注册

微信扫码登录

手机号码,快捷登录

手机号码,快捷登录

热搜: 合集
查看: 371|回复: 1

原码乘法器相关问题

[复制链接]
  • TA的每日心情
    郁闷
    2025-10-14 12:38
  • 1

    主题

    2

    帖子

    10

    积分

    新手入门

    Rank: 1

    积分
    10
    发表于 2025-10-13 17:07:34 | 显示全部楼层 |阅读模式
    用vivado做一个16位原码乘法器,共五个模块,分别是串口接收,数据缓冲器接收,乘法器,数据缓冲器发送,串口发送。其中串口接收是用来接收每一位原码,组成8位后发送给数据缓冲器接收,共发送四组,而数据接收缓冲器则是将两个8位组合16位,发送给乘法器计算后得到一个32位数据。现在问题是,前三个模块都没事,用数据发送缓冲器将32位数分四组发送后,得到的每组数据发送完成的信号时序不对,导致串口发送模块发送的数据也不对。以下仿真图中finish_flag4,finish_flag5和tx_data(也就是uart_tx)有问题,求大神指点,多谢!!!

    ////数据发送缓冲器模块 屏幕截图 2025-10-13 163802.png

    module shujv_tx(
        input Clk,
        input [31:0] y,  
        input Reset_n,
        input start_flag,
        input fankui,//uart_tx反馈的信号
                               
        output reg finish_flag,
        output reg [7:0] data_tx
    );                                             
                                      
        reg cnt;
        reg en;

       //计数逻辑
      always @(posedge Clk or negedge Reset_n) begin
            if(!Reset_n)
                cnt <= 0;
            else if (start_flag )
                cnt <= 0;
            else if ( fankui)begin
                if(cnt == 3)
                    cnt <= 0;
                else
                    cnt <= cnt + 1;
           end
        end

        //    //传输逻辑
        always @(posedge Clk or negedge Reset_n) begin
            if(!Reset_n)
                data_tx <= 8'b0;
            else if(en)begin
                case (cnt)
                    0: data_tx <= y[7:0];                       
                    1: data_tx <= y[15:8];        //传输8bit数据位
                    2: data_tx <= y[23:16];
                    3: data_tx <= y[31:24];
                    default: data_tx <= data_tx;
                endcase
            end
        end                  

        //使能逻辑
        always @(posedge Clk or negedge Reset_n) begin
            if(!Reset_n)
                en <= 0;
            else if((start_flag == 1)||(fankui == 1))
                en <= 1;
            else if(cnt ==3)
                en <= 0;
            else
                en <= 0;
        end

         //完成逻辑
        always @(posedge Clk or negedge Reset_n) begin
            if(!Reset_n)
                finish_flag <= 0;
            else if((en == 1)&&(cnt == 0))
                finish_flag <= 1;
            else if((en == 1)&&(cnt == 1))
                finish_flag <= 1;
            else if((en == 1)&&(cnt == 2))
                finish_flag <= 1;
            else if((en == 1)&&(cnt == 3))
                finish_flag <= 1;
            else
                finish_flag <= 0;
        end


    endmodule


    ////串口发送模块
    module uart_tx(Clk, Reset_n, Data,start_flag, tx_data, finish_flag);
        input Clk;
        input Reset_n;
        input start_flag;//开始发送信号(对应shujv_tx中的finish_flag)
        input [7:0]Data;//需要发送的数据信号(对应shujv_tx中的data_tx)
        output reg tx_data;
        output reg finish_flag;//发送完成信号(即fankui)

        parameter BAUD = 9600;//波特率
        parameter CLOCK_FREQ = 50_000_000;//系统频率50MHZ
        parameter MCNT_BAUD = CLOCK_FREQ/BAUD-1;//波特率计数最大值
        parameter MCNT_BIT = 10-1;//位计数最大值

        reg [29:0]baud_div_cnt;//波特率计数
        reg [3:0]bit_cnt;//位计数
        reg en_baud_cnt;//使能信号
        reg [7:0]r_Data;

        reg w_finish_flag;

        //使能信号控制逻辑
        always@(posedge Clk or negedge Reset_n)
        if(!Reset_n)
            en_baud_cnt <= 0;        
        else if(start_flag)
             en_baud_cnt <= 1;
         else if (w_finish_flag)
            en_baud_cnt <= 0;

    //波特率计数器
        always@(posedge Clk or negedge Reset_n)
        if(!Reset_n)
            baud_div_cnt <= 0;
        else if(en_baud_cnt)begin
                if(baud_div_cnt == MCNT_BAUD)
                    baud_div_cnt <= 0;
                else
                    baud_div_cnt <= baud_div_cnt+ 1'd1;
        end
        else
            baud_div_cnt <= 0;

       //位计数器        
        always@(posedge Clk or negedge Reset_n)
        if(!Reset_n)
            bit_cnt <= 0;
        else if(baud_div_cnt == MCNT_BAUD)begin
                if(bit_cnt == MCNT_BIT)
                    bit_cnt <= 0;
                else
                    bit_cnt <= bit_cnt+ 1'd1;
        end

       //锁定端口数据的D触发器
        always@(posedge Clk or negedge Reset_n)
        if(!Reset_n)
            r_Data <= 0;
        else if (start_flag)
            r_Data <= Data;
        else
            r_Data <= r_Data;

        //位发送逻辑
        always@(posedge Clk or negedge Reset_n)
        if(!Reset_n)
            tx_data <= 1'd1;
        else if (en_baud_cnt == 0)
            tx_data <= 1'd1;
        else begin
            case (bit_cnt)
                0:tx_data <= 1'd0;//只有开始传输的时候拉底,其余均拉高
                1:tx_data <=  r_Data[0];
                2:tx_data <=  r_Data[1];
                3:tx_data <=  r_Data[2];
                4:tx_data <=  r_Data[3];
                5:tx_data <=  r_Data[4];
                6:tx_data <=  r_Data[5];
                7:tx_data <=  r_Data[6];
                8:tx_data <=  r_Data[7];
                9:tx_data <=  1'd1;
                default:tx_data <= tx_data;
            endcase
        end

        //数据完成逻辑
    //    assign w_finish_flag = ((bit_cnt == 9)&&(baud_div_cnt == MCNT_BAUD));

        always@(posedge Clk) begin
        if(!Reset_n)
            w_finish_flag <= 0;
        else if((bit_cnt == 9)&&(baud_div_cnt == MCNT_BAUD))
            w_finish_flag <= 1;
        else
            w_finish_flag <= 0;
        end

        always@(posedge Clk)
            finish_flag <= w_finish_flag;

    endmodule


    回复

    使用道具 举报

  • TA的每日心情
    郁闷
    2025-10-14 12:38
  • 1

    主题

    2

    帖子

    10

    积分

    新手入门

    Rank: 1

    积分
    10
     楼主| 发表于 2025-10-13 17:15:12 | 显示全部楼层

    ////顶层
    module top(
        input Clk,
        input Reset_n,
        input uart_rx,
        output uart_tx
    );

        // 内部连线声明
        wire [7:0] rx_data;//uart_rx传输给shujvv_rx的数据
       
        wire finish_flag_1;
        wire finish_flag_2;
        wire finish_flag_3;
        wire finish_flag_4;
        wire finish_flag_5;//(fankui)
       
        wire [15:0] data_A, data_B;//shujv_rx传输给mult的数据
        wire [31:0] y;//mult传输给shujv_tx的数据

        wire [7:0] t_data;//shujvv_tx传输给uart_tx的数据
       
       

        // 串口接收模块实例化
        uart_rx u_uart_rx(
            .Clk(Clk),
            .Reset_n(Reset_n),
            .uart_rx(uart_rx),
            .finish_flag(finish_flag_1),
            .rx_data(rx_data)
        );

        // 数据接收缓存器实例化
        shujv_rx u_shujv_rx(
            .Clk(Clk),
            .Reset_n(Reset_n),
            .data_in(rx_data),
            .start_flag(finish_flag_1),
            .data_A(data_A),
            .data_B(data_B),
            .finish_flag(finish_flag_2)
        );

        // 乘法器核心实例化
        mult u_mult(
            .Clk(Clk),
            .Reset_n(Reset_n),
            .start_flag(finish_flag_2),
            .a(data_A),
            .b(data_B),
            .y(y),
            .finish_flag(finish_flag_3)
        );

        // 发送数据缓存器实例化
        shujv_tx u_shujv_tx(
            .Clk(Clk),
            .y(y),
            .Reset_n(Reset_n),
            .start_flag(finish_flag_3),
            .finish_flag(finish_flag_4),
            .data_tx(t_data),
            .fankui(finish_flag_5)
        );

        // 串口发送模块实例化
        uart_tx u_uart_tx(
            .Clk(Clk),
            .Reset_n(Reset_n),
            .start_flag(finish_flag_4),
            .Data(t_data),
            .tx_data(uart_tx),
            .finish_flag(finish_flag_5)
        );

    endmodule
    回复 支持 反对

    使用道具 举报

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

    本版积分规则

    QQ|小黑屋|Archiver|芯路恒电子技术论坛 |鄂ICP备2021003648号

    GMT+8, 2025-11-22 04:52 , Processed in 0.052023 second(s), 29 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc. Template By 【未来科技】【 www.wekei.cn 】

    快速回复 返回顶部 返回列表