和你一起从零开始写RISC-V处理器(2)

2023-11-16

RISC-V加法指令的实现(Ⅱ)

上期回顾

本文首发于公众号:FPGA学习者,关注公众号,获取更多资料与内容。
上期说到,要实现加法指令,需要编写以下八个模块:
在这里插入图片描述
先总体看一下,该部分的模块连接的框图如下:
在这里插入图片描述Yx_risc-v(名称根据自身喜好命名)内核内部模块连接框图为:
在这里插入图片描述


一、正片开始——编写各个模块

①pc_reg模块

在这里插入图片描述
pc_reg模块主要用来根据时钟信号产生指令地址,因为ROM中一般每个存储空间有8位,所以四个存储空间才能完全存放一个指令信号,故,该模块的指令地址信号每时钟下进行加4操作。代码如下:


//该模块主要产生指令地址信号
module pc_reg(
  input    wire       clk    ,
  input   wire       rst_n    ,
  output   reg [31:0]   pc_o      //输出的指令地址
);

  always@(posedge clk or negedge rst_n)begin
    if(~rst_n)begin
      pc_o <= 32'b0;
    end
    else begin
      pc_o <= pc_o + 3'd4;
    end
  end
endmodule
//复位的时候,指令地址指向第0个指令寄存器,ROM的最开始
//其余时刻,不断加4,因为每个指令占用4个空间

②if模块

在这里插入图片描述
if(instruction fetch)取指模块,将输入的指令地址,送至ROM中,ROM根据指令地址产生相应的指令信号送入if取指模块,if再将指令信号和指令地址信号输出至下一个模块。代码如下:


//取指模块,从ROM中取出指令信号,组合逻辑
module ifeth(    //由于if为verilog关键字,所以使用ifetch
  //from pc_reg
  input   wire [31:0]   pc_addr_i    ,
  //from rom
  input   wire [31:0]   rom_inst_i    ,      //取出的命令,rom返回的指令
  //to rom
  output   wire [31:0]   if2rom_addr_o  ,      //将指令地址给rom,rom返回指令
  //to if_id
  output   wire [31:0]   inst_addr_o    ,      //将指令地址送入下一个模块打拍
  output   wire [31:0]   inst_o            //将指令送入下一个模块打拍

);
  assign if2rom_addr_o = pc_addr_i;
  assign inst_addr_o = pc_addr_i;
  assign inst_o = rom_inst_i;
endmodule

③rom模块

在这里插入图片描述 rom模块根据取指模块给出的地址,将相应的指令返回给取指模块,代码如下:

//存放指令的ROM
module rom(
  input   wire   [31:0]   inst_addr_i,
  output   reg  [31:0]   inst_o
);
  reg [31:0] rom_mem [0 : 4095];      //4096个32bit空间
  //这里一次性实现命令的32位了,和原本想法略有不符
  //所以下面要一次进行加一的操作,所以才右移4位。
  always@(*)begin
    inst_o = rom_mem[inst_addr_i >> 2];  //右移两位,缩小四倍,实现每次加一操作
  end
endmodule

对于rom模块,可以使用8位的rom,然后再进行逻辑处理;此处使用的比较简单,直接为32位rom,将本来步进加4的地址信号,右移两位(除以4)实现步进加1操作。

④if_id模块

在这里插入图片描述
对于if_id模块,实现简单的打一拍操作,防止出现时序违例。代码如下:

//时序逻辑,进行打拍
`include  "defines.v"
module if_id(
  input   wire         clk      ,
  input   wire         rst_n      ,
  input   wire [31:0]   inst_i      ,
  input   wire [31:0]   inst_addr_i  ,
  output   wire [31:0]   inst_addr_o,        //打一拍之后的地址输出
  output   wire [31:0]   inst_o            //打一拍之后的指令输出
);
  //例化D触发器,实现打一拍的逻辑
  dff_set #(32) dff1(clk,rst_n,`INST_NOP,inst_i,inst_o);
  dff_set #(32) dff2(clk,rst_n,32'b0,inst_addr_i,inst_addr_o);

endmodule

上述代码中包含头文件defines.v,该文件中主要是相关命令的宏定义,该文件获取方式在文末给出。

因为后续还有模块会用到寄存器打拍的操作,所以将D触发器打拍单独写为一个模块,上述if_id模块对其进行了例化。D触发器模块代码如下:

//D触发器模块,将输入的数据打一拍
module dff_set #(
  parameter DW = 32
)
(
  input   wire           clk    ,
  input   wire           rst    ,
  input   wire   [DW-1 : 0] set_data  ,  //复位时的信号
  input   wire   [DW-1 : 0] data_i  ,
  output   reg    [DW-1 : 0] data_o
);
  always@(posedge clk or negedge rst)begin
    if(~rst)begin
      data_o <= set_data;        //置位信号
    end
    else begin
      data_o <= data_i;
    end
  end
endmodule

⑤id模块

在这里插入图片描述
id模块对前级输入的指令信号进行译码,通过译码得出寄存器的地址信号,将该地址信号送至寄存器组,寄存器组返回相应的数据,然后向后级输出操作数1、操作数2、需要回写的目的寄存器地址和写寄存器使能信号。代码相对较长,此处仅放端口定义,完整代码获取方式文末给出。

该模块主要根据操作码和funct3功能码进行命令的判断。

module id(
  //from if_id
  input   wire   [31:0]   inst_i        ,        //前级输入的指令
  input   wire  [31:0]   inst_addr_i    ,        //前级输入的指令地址
  //to regs
  output   reg   [4:0]    rs1_addr_o  ,          //给寄存器组的地址
  output   reg   [4:0]   rs2_addr_o  ,          //给寄存器组的地址
  //from regs
  input   wire  [31:0]   rs1_data_i    ,        //从寄存器中取出的数据
  input   wire  [31:0]   rs2_data_i    ,        //从寄存器中取出的数据
  //to id_ex
  output   reg   [31:0]   inst_o      ,        //输出到后边的指令
  output   reg   [31:0]   inst_addr_o    ,        //输出到后边的指令地址
  output   reg   [31:0]   op1_o      ,        //操作数1
  output   reg   [31:0]   op2_o      ,        //操作数2
  output   reg   [4:0]     rd_addr_o    ,        //目的寄存器的地址,回写的时候用
  output   reg            reg_wen_o            //寄存器使能,写寄存器的时候用
);

⑥regs模块

在这里插入图片描述
寄存器组,一方面接收来自译码模块的地址信号并返回相应的数据信号,另一方面接收来自执行模块的地址信号、数据信号和使能信号。代码如下:


//寄存器组

module regs(
  input   wire       clk        ,
  input   wire      rst_n        ,
  //from id
  input   wire [4:0]   reg1_raddr_i  ,
  input   wire [4:0]   reg2_raddr_i  ,
  //to id
  output   reg [31:0]   reg1_rdata_o  ,
  output   reg [31:0]   reg2_rdata_o  ,
  //from ex                                  //从ex回来的地址和数据和使能信号
  input   wire [4:0]  reg_waddr_i  ,
  input   wire [31:0]  reg_wdata_i  ,
  input           reg_wen_i
);

  integer i;
  reg [31:0] regs [0 : 31];

  always@(*)begin
    if(~rst_n)begin
      reg1_rdata_o = 32'b0;
    end
    else if(reg1_raddr_i == 5'b0)
      reg1_rdata_o = 32'b0;
    else if(reg_wen_i && reg1_raddr_i == reg_waddr_i)    //这个地方主要是在指令冲突的时候
      reg1_rdata_o = reg_wdata_i;                //不需要通过读取回写之后的数据,直接进行判断后由该寄存器内部数据传递即可
    else
      reg1_rdata_o = regs[reg1_raddr_i];
  end
  always@(*)begin
    if(~rst_n)begin
      reg2_rdata_o = 32'b0;
    end
    else if(reg2_raddr_i == 5'b0)
      reg2_rdata_o = 32'b0;
    else if(reg_wen_i && reg2_raddr_i == reg_waddr_i)
      reg2_rdata_o = reg_wdata_i;
    else
      reg2_rdata_o = regs[reg2_raddr_i];
  end
  always@(posedge clk or negedge rst_n)begin
    if(~rst_n)begin                            //复位的时候,对寄存器组进行初始化
      for(i =  0 ; i < 31; i = i + 1)begin
        regs[i] <= 32'd0;    
      end
    end
    else if(reg_wen_i && reg_waddr_i != 5'b0) begin      //不能写入零寄存器
      regs[reg_waddr_i] <= reg_wdata_i;
    end
  end
endmodule

在上述代码的注释处描述的是指令冲突时的操作:如果第二条指令的源寄存器刚好是第一条指令的目的寄存器,(即:第二条指令的源寄存器地址等于第一条指令的目的寄存器地址),那就直接将执行模块得到的数据通过组合逻辑赋值给当前需要读出的源寄存器的数据,同时按照时序逻辑写入regs中去(每次回写都是必须要写的)。可参照下图以及上述程序进行理解上面那段话的含义。
在这里插入图片描述

⑦id_ex模块

在这里插入图片描述
对数据实现打一拍输出。

//进行打一拍输出
`include  "defines.v"
module id_ex(
  input   wire         clk      ,
  input   wire         rst_n      ,
  //from id
  input   wire [31:0]   inst_i      ,
  input   wire [31:0]   inst_addr_i  ,  
  input   wire [31:0]   op1_i      ,
  input   wire [31:0]   op2_i      ,
  input   wire [4:0]     rd_addr_i  ,
  input   wire          reg_wen_i  ,
  //to ex
  output   wire [31:0]   inst_o    ,          //输出到后边的指令
  output   wire [31:0]   inst_addr_o  ,          //输出到后边的指令地址
  output   wire [31:0]   op1_o    ,          //操作数1
  output   wire [31:0]   op2_o    ,          //操作数2
  output   wire [4:0]     rd_addr_o  ,          //目的寄存器的地址,回写的时候用
  output   wire          reg_wen_o            //寄存器使能,写寄存器的时候用

);
  dff_set #(32) dff1(clk,rst_n,`INST_NOP,inst_i,inst_o);
  dff_set #(32) dff2(clk,rst_n,32'd0,inst_addr_i,inst_addr_o);
  dff_set #(32) dff3(clk,rst_n,32'd0,op1_i,op1_o);
  dff_set #(32) dff4(clk,rst_n,32'd0,op2_i,op2_o);
  dff_set #(5) dff5(clk,rst_n,5'd0,rd_addr_i,rd_addr_o);
  dff_set #(1) dff6(clk,rst_n,1'b0,reg_wen_i,reg_wen_o);

endmodule

⑧ex模块

在这里插入图片描述
ex模块,实现执行和回写两个部分的内容,主要根据操作码、功能码funct3和功能码funct7来判断命令具体是哪一条,然后再执行相应的操作。

将操作后的数据根据地址信号和使能信号,回写到regs寄存器数组中。由于该部分代码较长,仅放端口定义,完整代码获取方式文末给出。


`include  "defines.v"
//执行模块
module ex(
  //from id_ex
  input   wire [31:0]   inst_i      ,
  input   wire [31:0]   inst_addr_i  ,  
  input   wire [31:0]   op1_i      ,
  input   wire [31:0]   op2_i      ,
  input   wire [4:0]     rd_addr_i  ,
  input   wire          reg_wen_i  ,
  //to regs
  output   reg [4:0]     rd_addr_o  ,
  output   reg [31:0]     rd_data_o  ,
  output   reg        rd_wen_o
);

好了,至此,所有的模块都绿了,这样就行了嘛?当然不行,要全绿才可以!下面要编写顶层模块将上述除ROM外的所有模块进行例化。

二、顶层模块搭建

在这里插入图片描述
好了,这下全绿了,该部分就是将上述除ROM外的七个模块进行例化,注意之间的连线,一步一步来,尽量不要出错,代码过长,此处仅放置端口定义,完整代码获取方式在文末给出:

//顶层文件
//将除了ROM之外的模块连接起来,ROM为外设,不是内核
`include  "defines.v"
`timescale 1ns/1ns
module Yx_risc_v(
  input   wire       clk      ,
  input   wire       rst_n      ,
  input   wire [31:0] inst_i      ,
  output   wire [31:0] inst_addr_o
);

除此之外,还要编写一个soc顶层文件,例化该内核模块和rom模块,代码如下:

//顶层文件
//`include  "defines.v"
module Yx_risc_v_soc(
  input   wire       clk  ,
  input   wire       rst_n
);
  //Yx_risc_v to rom
  wire [31:0] Yx_risc_v_inst_addr_o;
  //rom to Yx_risc_v
  wire [31:0] rom_inst_o;
  Yx_risc_v Yx_risc_v_inst(
    .clk          (clk                ),
    .rst_n        (rst_n              ),
    .inst_i        (rom_inst_o          ),
    .inst_addr_o    (Yx_risc_v_inst_addr_o  )
);
  rom rom_inst(
    .inst_addr_i      (Yx_risc_v_inst_addr_o  ),
    .inst_o        (rom_inst_o          )
);
endmodule

如此便可形成如下结构:

在这里插入图片描述

三、测试文件编写

或许你正看上面的文章看的津津有味,有没有突然想到,哎?光说从rom中读取指令,那rom中的指令从哪里来呢?

这里使用了一个系统函数:$readmemb,通过该函数将外部.txt文件中的指令读取到rom中即可。
testbench文件编写如下:


`timescale 1ns/1ns
module tb;
  reg clk;
  reg rst_n;
Yx_risc_v_soc Yx_risc_v_soc_inst(
  .clk(clk),
  .rst_n(rst_n)
);
  always #10 clk = ~clk;
  initial begin
    clk = 0;
    rst_n = 0;
    #30;
    rst_n = 1'b1;
  end
  //rom 初始值
  initial begin  //第一个参数为文件名,第二个参数为需要写入的寄存器
    $readmemb("inst_data_ADD.txt",tb.Yx_risc_v_soc_inst.rom_inst.rom_mem);
  end
  initial begin
    while(1)begin
      @(posedge clk)
      $display("x27 register value is %d",tb.Yx_risc_v_soc_inst.Yx_risc_v_inst.regs_inst.regs[27]);
      $display("x28 register value is %d",tb.Yx_risc_v_soc_inst.Yx_risc_v_inst.regs_inst.regs[28]);
      $display("x29 register value is %d",tb.Yx_risc_v_soc_inst.Yx_risc_v_inst.regs_inst.regs[29]);
      $display("---------------------------");
      $display("---------------------------");
    end
  end
endmodule

编写的.txt文件如下:


00000000111100000000110110010011
00000001100100000000111000010011
00000001110011011000111010110011

对应的指令为:
在这里插入图片描述这样运算得到的结果应该为40;ModelSim中仿真结果如下:
在这里插入图片描述
结果是正确的,编写的代码应该也问题不大。看看波形吧,如下:
在这里插入图片描述
确实也是分三个时钟周期执行完一条指令。
好,先测到这里,其他详细测试暂时不写了;今天内容有些超量了哈哈。

总结

上述代码,关注公众号:FPGA学习者,后台回复【指令添加】即可获取全部工程文件。

往期精彩

和你一起从零开始写RISC-V处理器(1)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

和你一起从零开始写RISC-V处理器(2) 的相关文章

  • SD卡读写实验(SPI模式)

    对于 SD 卡的 SPI 模式而言 采用的 SPI 的通信模式为模式 3 即 CPOL 1 CPHA 1 在 SD 卡 2 0 版 本协议中 SPI CLK 时钟频率可达 50Mhz SD 卡的 SPI 模式 只用到了 SDIO D3 SP
  • 笔试

    文章目录 前言 40 复位电路设计 1 recovery time和removal time 2 同步复位和异步复位 3 异步复位同步释放 本文参考 往期精彩 前言 嗨 今天来学习复位电路设计相关问题 微信关注 FPGA学习者 获取更多精彩
  • 小梅哥Xilinx FPGA学习笔记9——语法(阻塞与非阻塞赋值)

    阻塞赋值与非阻塞赋值详解 注意 阻塞赋值 1 设计文件 2 激励文件 3 原理图 4 仿真图 非阻塞赋值 1 设计文件 2 激励文件 3 原理图 4 仿真图 注意 阻塞赋值与非阻塞赋值 只有在时序逻辑中才有 不是阻塞赋值 也不是非阻塞赋值
  • RISC-V嵌入式开发准备篇2:嵌入式开发的特点介绍

    原文出处 https mp weixin qq com s ljYZwMj3JaPN29dTAXA3bQ 随着国内第一本RISC V中文书籍 手把手教你设计CPU RISC V处理器篇 正式上市 越来越多的爱好者开始使用开源的蜂鸟E203
  • 握手2倍速率进,一倍速率出[verilog]

    module two to one parameter WORD LEN 33 input clk input arst input 2 WORD LEN 1 0 i din input i din valid output o din r
  • 吃透Chisel语言.18.Chisel模块详解(五)——Chisel中使用Verilog模块

    Chisel模块详解 五 Chisel中使用Verilog模块 上一篇文章讲述了用函数实现轻量级模块的方法 可以大幅度提升编码效率 Chisel中也提供了一些好用的函数 方便我们编写代码 也方便Chisel编译器优化生成的硬件电路 在Chi
  • 八段数码管动态显示(输入数据为BCD编码)

    八段数码管动态显示 输入数据为BCD编码 一 数码管概述 图1 八段共阴数码管内部等效原理图 图2 八段共阳数码管内部等效原理图 上面两图分别是对应八段共阴 共阳的数码管内部等效图 共阴是将八个LED数码管的阴极连接在一起接低 阳极segm
  • IC数字后端

    在 innovus 里面 有时候我们需要控制 tie cell 的 fanout 和 net length 来避免 tie cell 可能出现 max transition 或者 max fanout 的违例 一般来说 只要 fanout
  • 【电子技术】什么是LFSR?

    目录 0 前言 1 数学基础 1 1 逻辑异或 1 2 模2乘法 和 模2除法 2 线性反馈移位寄存器LFSR 3 抽头和特征多项式 4 阶线性反馈移位寄存器实例 0 前言 线性反馈移位寄存器 Linear Feedback Shift R
  • [从零开始学习FPGA编程-24]:进阶篇 - 基本组合电路-编码器与译码器(Verilog语言)

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 https blog csdn net HiWangWenBing article details 125247358 目录 前言 Veri
  • 如何用GDB调试交叉编译的QEMU程序?

    我在使用 GDB 调试 QEMU 中运行的简单程序时遇到问题 GDB似乎无法找到我在程序中的位置 因为它总是显示 作为我当前的位置 并且它永远不会达到我设置的任何断点 在一个终端中 我运行 QEMU cat add c int main i
  • Risc-V:能够利用 GCC 的简单 RV32I 实现的最低 CSR 要求

    对于能够运行 GCC 生成的机器代码的 RV32I 最低的 CSR 要求是什么 我正在考虑一个简单的基于 fpga 嵌入式 的实现 不需要虚拟内存或 Linux 支持 另外 我应该使用什么 GCC 标志来防止它使用未实现的 CSR 相关指令
  • 【ZYNQ学习】PL第一课

    这节课讲什么 这节课的名字本来是想写为LED 但这一课里除了LED也有按键 又想换为GPIO控制 但关于PL的GPIO控制 不应该这么草率和简单 而且这一课有很多和ZYNQ或者PL关联性不强的东西要说 所以我写了删删了写改了好几遍 终于定为
  • 串口通信知识点总结

    串口是串行接口 serial port 的简称 也称为串行通信接口或COM接口 串口通信是指采用串行通信协议 serial communication 在一条信号线上将数据一个比特一个比特地逐位进行传输的通信模式 串口按电气标准及协议来划分
  • [Verilog] Verilog 基本格式和语法

    主页 元存储博客 全文 3000 字 文章目录 1 声明格式 1 1 模块声明 1 2 输入输出声明 1 3 内部信号声明 1 4 内部逻辑声明
  • 凿子3.功能模块Mux4

    我正在按照文档学习 Chisel在 Github 上 https github com ucb bar chisel3 wiki Short 20Users 20Guide 20to 20Chisel 到目前为止 一切都完美无缺 但我还是卡
  • 如何为 Risc-V(汇编语言)编写旋转操作 我们有像 8086 中那样的命令吗?

    我以前使用过8086的汇编语言 8086中的旋转操作只是一个命令 但我在 Risc V 汇编语言中找不到旋转操作的特定关键字 看起来扩展 B 最终应该定义这样的指令 在那之前你必须使用左移和右移来组合它 这是 MIPS32R2 rotrv
  • MINI-UTDE 10 BASE-T 集成控制器

    MINI UTDE 10 BASE T 集成控制器 MINI UTDE 10 BASE T 拥有多达三个本地I O板和远程I OS总线通信 为用户提供了一系列生产单元功能的单一控制点 包括诸如夹头 反馈器和辅助机器等外围生产设备 支持所有主
  • RISC-V 使用 LUI 和 ADDI 构建 32 位常量

    LUI 加载立即数 用于构建32位常量并使用U型格式 LUI 将 U 立即数放入目标寄存器 rd 的高 20 位 并用零填充最低 12 位 我在手册中找到了这个 但是如果我想将 0xffffffff 移动到寄存器 我需要的所有代码是 LUI
  • GDB 中断命令不会在命令文件中执行

    我有一个调试脚本 它执行以下操作 设置两个断点 让我们称呼他们吧start and end断点 启动后 脚本将继续执行 直到start命中断点 once start命中断点 我执行单步执行 直到end命中断点 这是我的命令文件 end br

随机推荐

  • umijs----路由(修改路由的某一个path )

    1 在src下创建app js ts tsx 2 修改路由 export function patchRoutes routes routes为 umirc ts中设置的routes数组 可以使用数组的方法插入删除 运行时在最前面插入一个路
  • Webpack配置Vue热更新

    Webpack配置Vue热更新 需要的包 cnpm i vue webpack webpack cli webpack dev server html webpack plugin clean webpack plugin style lo
  • 【正点原子MP157连载】第七章 认识HAL库-摘自【正点原子】STM32MP1 M4裸机CubeIDE开发指南

    1 实验平台 正点原子STM32MP157开发板 2 购买链接 https item taobao com item htm id 629270721801 3 全套实验源码 手册 视频下载地址 http www openedv com t
  • selenium4

    1 单选框和复选框 单选框 type radio 定位 gt 点击 判断是否被选中 元素 is selected 复选框 type checkbox 只选择一个 gt 同单选框一样 全选 定位所有复选框 遍历 判断是否被选中 点击 选择部分
  • java入门六:java基础终章

    1 static关键字 静态变量和类一起加载 final修饰后的类无法被继承 2 抽象类 abstract修饰符可以用来修饰方法也可以修饰类 如果修饰方法 那么该方法就是抽象方法 如果修饰类 那么该类就是抽象类 抽象类中可以没有抽象方法 但
  • Linux Shell程序设计(2)

    实验十一 Shell程序设计 2 一 实验要求 综合运用shell编程知识进行设计性编程 二 实验内容和实验步骤 1 实验内容 假设你作为某工厂生产管理员 需要负责统计各车间每天生产的产品数据 你的计算机安装了双硬盘 为了保证数据安全 你在
  • 【定位问题】Mybatis-plus的selectPage()分页查询不生效问题

    背景 项目需要从mybits切换到mubits plus 但是我在进行分页查询的时候 发现一直不生效 问题原因 添加监听器 配置如下 Configuration MapperScan com baomidou mybatisplus sam
  • parted创建硬盘分区并创建LVM

    目的 将两个三T的硬盘做成LVM sdc sdd 一 parted将硬盘进行分区 1 parted的命令方式 Parted 命令分为两种模式 命令行模式和交互模式 1 命令行模式 parted option device command 该
  • 【原创】第一个iOS应用程序

    摘要 第一个iOS应用程序 包括获取控件 绑定事件 设置属性等内容 iOS Objective C 目录 第一章 窗口与应用程序 第二章 添加视图 2 1 从nib文件初始化视图 2 2 使用脚本添加视图 第三章 添加子视图 3 1 通过x
  • 制作自己的 Kindle 电子书

    想象以下场景 你刚收到一台新的 Kindle Paperwhite 心中已然响起了轰轰烈烈的 我今年 或这个冬天 一定要阅读 100 本书 结果发现 想看的书 Amazon 上找不到 或者排版很糟糕 如何解决 自己动手做呗 准备工作 我使用
  • UE4 UI实现改键功能

    主要内容 本文主要讲解如何在UI中实现自定义按键的功能类似于游戏中的改键操作 用到的是UE4自带的第三人称案例 因为第三人称自带了小白人和几个按键绑定就不用再手动去设置 实现步骤 1 创建两个UMG用来展示UI效果 1 创建WBP Key
  • C++链表合并

    有l1和l2两个链表 这两个链表降序排列 把l2合并到l1中 并按降序排列 同时清空l2链表 例如l1 9 8 7 6 l2 12 11 10 5 4 3 2 1 合并后l1 12 11 10 9 8 7 6 5 4 3 2 1 l2 in
  • 【Android】利用intent启动浏览器

    文章目录 一 默认浏览器 二 指定浏览器 三 选择浏览器 一 默认浏览器 需要设置Action和Date属性 构造 Uri uri Uri parse https www baidu com Intent intent new Intent
  • SCADE Suite 状态机之变量隐式赋值

    SCADE Suite 状态机之变量隐式赋值 1 变量的隐式赋值 目的 简化模型设计 Last 只要没有显示赋值 便取上一周期的数值 Default 只要没有显示赋值 便取默认设置的数值 优先级更高 设置方法 2 定义变量的Last值 1
  • LeetCode 817:链表组件(计数)

    解法一 常规解法 建图 DFS 时间复杂度O n O n 空间复杂度因为需要存储图 所以是O n 这种方法是通解 对于所有图都适用 Definition for singly linked list struct ListNode int
  • lua元表以及元方法

    知微出凡 lua元表以及元方法 lua中的变量是没有数据类型的 值有类型 类型有八种nil number boolean string function thread userdata以及table Lua 中的每个值都可以有一个 元表 这
  • 62.[GIS基础]笛卡尔坐标系

    文章目录 笛卡尔坐标系 多坐标系 坐标系的嵌套 坐标变换 坐标系转换 转载请注明原始链接 http blog csdn net a464057216 article details 54578069 后续此博客不再更新 欢迎大家搜索关注微信
  • 基于粒子群算法(PSO)优化径向基神经网络(PSO-RBF)的分类预测。matlab代码,优化参数为扩散速度,采用交叉验证。多特征输入单输出的二分类及多分类模型。程序内注释详细,直接替换数据就

    清空环境变量 warning off 关闭报警信息 close all 关闭开启的图窗 clear 清空变量 clc 清空命令行 读取数据 res xlsread 数据集 xlsx 分析数据 num class length unique
  • 抛去容抗角度,从电容充放电角度理解RC低通滤波器

  • 和你一起从零开始写RISC-V处理器(2)

    RISC V加法指令的实现 文章目录 RISC V加法指令的实现 上期回顾 一 正片开始 编写各个模块 pc reg模块 if模块 rom模块 if id模块 id模块 regs模块 id ex模块 ex模块 二 顶层模块搭建 三 测试文件