计算机组成原理实验——五、单周期CPU设计

2023-11-15

一、实验目的

  1. 掌握指令执行过程的5个阶段
  2. 掌握每条指令的数据通路选择
  3. 掌握译码器和控制器的功能和实现
  4. 掌握数据输入输出处理的方法
  5. 实现risc-v中RV32I指令的单周期CPU
  6. 利用实现的risc-v CPU实现平方数

二.实验内容

  1. 实现risc-v中37条RV32I指令的单周期 cpu;
  2. 完成1后在该cpu上实现斐波那契数。

三、实验程序

rom
请添加图片描述

dataRAM

请添加图片描述
ins文件(斐波那契数列的机器代码)
请添加图片描述

top.v

module top(
    input clk,
    input rst,
    input [3:0] n,
    output [2:0] an,
    output [6:0] out
    );
    wire[31:0] temp;
    CPU mycpu(.clk(clk),.rst(rst),.data(n),.result(temp));
    show myshow(.clk(clk),.rst(rst),.result(temp[11:0]),.an(an),.out(out)); 
endmodule

CPU.v

module CPU(
    input clk,
    input rst,
    input [3:0] data,         //n
    output [11:0] result       //f(n)
    );
    //声明wire总线,用来连接各个模块
    wire[31:0]nextaddr,addr,addr4,insdata,rdata1,rdata2,rwdata,a,b,f,mdata,imm12_exp,imm20_exp,addr_branch,addr_jal,addr_jalr,out;
    wire[4:0] rs1,rs2,rd;
    wire[6:0] opcode;
    wire[2:0] func,mm;
    wire[1:0] pcsource;
    wire dis,con,rwe,mwe,isimm,isfpc,is20,isfm,ispc4;
    wire[11:0] imm12;
    wire[19:0] imm20;
    wire[3:0] aluop;
    wire ecall; // 判断是否为中断
    wire inflag, outflag, finish;   // 输入标识,输出标识,结束标识
    
    // 实例化PC
    PC mypc(
        .rst(rst),
        .clk(clk),
        .next(nextaddr),
        .finish(finish),
        .addr(addr)
    );
        
    // 实例化ROM
    InsROM ir(
        .a(addr),
        .spo(insdata)
     );
    
    // 实例化ID
    ID myid(
        .ins(insdata),
        .rs1(rs1),
        .rs2(rs2),
        .rd(rd),
        .opcode(opcode),
        .func(func),
        .dis(dis),
        .imm12(imm12),
        .imm20(imm20),
        .ecall(ecall)
    );
    
    // 实例化控制单元
    ControlUnit2 mycu(
        .opcode(opcode),
        .func(func),
        .dis(dis),
        .c(con),
        .pcs(pcsource),
        .rwe(rwe),
        .mwe(mwe),
        .mm(mm),
        .aluOP(aluop),
        .isimm(isimm),
        .is20(is20),
        .isfpc(isfpc),
        .isfm(isfm),
        .ispc4(ispc4)
    );    

    assign inflag=ecall?((rs1==10&&rdata1==5)?1:0):0;   // x[10]=5,输入   
    assign outflag=ecall?((rs1==10&&rdata1==1)?1:0):0;  // x[10]=1, 输出
    assign finish=ecall?((rs1==10&&rdata1==10)?1:0):0;  // x[10]=10,结束
    assign rwdata=inflag?data:(ispc4?addr4:(isfm?mdata:f)); // 输入中断,x[10]=data
    assign result=outflag?rdata2:result;    // 输出中断,result=x[11]
    // 实例化寄存器堆
    RegFiles myrf(
        .raddr1(rs1),
        .rdata1(rdata1),
        .raddr2(rs2),
        .rdata2(rdata2),
        .waddr(rd),
        .wdata(rwdata),
        .we(rwe),
        .clk(clk)
    );
    
    // 将12位立即数符号扩展位32位
    assign imm12_exp={{20{imm12[11]}},imm12};
    // 将20位立即数符号扩展位32位
    assign imm20_exp={{12{imm20[19]}},imm20};      
    // 获取a的数据 来源于addr、rdata1
    assign a=isfpc?addr:rdata1;
    // 获取b的数据,来源于imm12、imm20或rdata2
    assign b=isimm?(is20?imm20_exp:imm12_exp):rdata2;
    
    // 实例化ALU
    ALU myalu(
        .a(a),
        .b(b),
        .op(aluop),
        .f(f),
        .c(con)
    );
            
    // 实例化RAM
    NEWRAM nr(
       .maddr(f),
       .mwdata(rdata2),
       .clk(clk),
       .we(mwe),
       .mm(mm),
       .mdata(mdata)
    );
    
    // 计算顺序指令地址  pc+4
    assign addr4=addr+4;
    // 下一条指令的地址
    assign nextaddr=pcsource[1]?(pcsource[0]?{f[31:1],1'b0}:f):(pcsource[0]?(imm12_exp<<1)+addr:addr4);

    initial
    begin
        $monitor($time,,"当前指令地址=%h,指令=%h",addr,insdata);  
        $monitor($time,,"寄存器读端口1:编号=%d,数据=%h",rs1,rdata1);  
        $monitor($time,,"寄存器读端口2:编号=%d,数据=%h",rs2,rdata2);
        $monitor($time,,"立即数=%h",b); 
        $monitor($time,,"寄存器写地址=%d,写数据=%h,写使能端=%b", rd,rwdata,rwe); 
        $monitor($time,,"输入标识=%d, 输出标识=%d,结束标识=%d",inflag,outflag,finish); 
    end
        
endmodule

PC.v

module PC(
    input rst,
    input clk,
    input [31:0] next,
    input finish,
    output reg [31:0] addr
    );
    
    always @(posedge clk)
        if(rst)
            addr<=32'h0;
        else
            if (!finish)
                addr<=next;  

//initial
//    begin
//        $monitor($time,,"PC Input: next=%h", next);
//        $monitor($time,,"PC Output: addr=%h", addr);
//    end
        
endmodule

module ID(
    input [31:0] ins,       // 指令
    output [4:0] rs1,       // 参数信息(REGFILES)
    output [4:0] rs2,       // 参数信息(REGFILES)
    output [4:0] rd,        // 参数信息(REGFILES)
    output [6:0] opcode,    // 身份信息
    output [2:0] func,      // 身份信息(func3和func7)
    output [11:0] imm12,    // 12位立即数
    output [19:0] imm20,    // 20位立即数
    output dis,             // 区分码,指令的第30位
    output reg ecall       // 是否为中断
    );

// 判断是否为ecall指令    
    always @(*)
    begin
        if (ins==32'h00000073) 
            ecall=1'b1;
        else
            ecall=1'b0;
    end
    
    assign opcode=ins[6:0];
    assign rd=ecall?10:ins[11:7];   // ecall指令,rd=10
    assign func=ins[14:12];         
    assign rs1=ecall?10:ins[19:15]; // ecall指令, rs1=10
    assign rs2=ecall?11:ins[24:20]; // ecall指令, rs2=11
    assign dis=ins[30];

    wire I_type,S_type,B_type,J_type,U_type;
    // 00x0011  I指令  1100111   jalr
    assign I_type=~ins[6]&~ins[5]&~ins[3]&~ins[2]&ins[1]&ins[0]|
                  (&ins[6:5])&~(|ins[4:3])&(&ins[2:0]);  
     // 0100011  S指令        
    assign S_type=~ins[6]&ins[5]&~(|ins[4:3])&(&ins[1:0]); 
    // 1100011  B指令
    assign B_type=(&ins[6:5])&~(|ins[4:3])&(&ins[1:0]);   
    // 0x10111 U指令
    assign U_type=~ins[6]&ins[4]&~ins[3]&(|ins[2:0]);
    // 1101111 jal
    assign J_type=(&ins[6:5])&~ins[4]&(&ins[3:0]);
       
    assign imm12={12{I_type}}&ins[31:20]|
                 {12{B_type}}&{ins[31],ins[7],ins[30:25],ins[11:8]}|
                 {12{S_type}}&{ins[31:25],ins[11:7]};
    assign imm20={20{U_type}}&ins[31:12]|
                 {20{J_type}}&{ins[31],ins[19:12],ins[20],ins[30:21]};

//initial
//    begin
//        $monitor($time,,"ID Output: ecall=%h", ecall);
//        $monitor($time,,"ID Input: ins=%h", ins);
//        $monitor($time,,"ID Output: rs1=%h, rs2=%h, rd=%h, opcode=%h, func=%h, imm12=%h, imm20=%h",rs1,rs2,rd,opcode,func,imm12,imm20);
//    end
endmodule

ControlUnit2.v

module ControlUnit2(
    input [6:0] opcode,
    input [2:0] func,
    input dis,
    input c,                //是否满足B类指令的跳转条件 =1  满足
    output reg [1:0]pcs,    //下一条指令地址来源方式   =00 顺序执行   =01 有条件跳转   =10  jal    =11  jalr
    output reg rwe,         //寄存器写使能端   =1
    output reg mwe,         //RAM写使能端      =1
    output reg [2:0] mm,    //RAM读写控制方式
    output reg [3:0] aluOP,//ALU运算类型
    output reg isimm,      //b是否是立即数
    output reg is20,       //b是否是20位的立即数
    output reg isfpc,      //a是否来源于pc
    output reg isfm,       //rwdata是否来源于mem
    output reg ispc4       //rwdata是否来源于pc+4
    );
    always @(*)
    begin
        case(opcode)
            7'b0110011: // R类指令
            begin
                pcs=2'b00;
                rwe=1'b1;
                mwe=1'b0;
                mm=3'b0;
                isimm=1'b0;
                is20=1'b0;
                isfpc=1'b0;
                isfm=1'b0;
                ispc4=1'b0;
                case(func)
                    3'b000: 
                    begin
                        if (dis==0)
                            aluOP=4'b0000;  // add 加法
                        else
                            aluOP=4'b0001;  // sub 减法
                    end
                    3'b001: aluOP=4'b0111;  // sll 左移指令
                    3'b010: aluOP=4'b0101;  // slt 有符号数比较
                    3'b011: aluOP=4'b0110;  // sltu 无符号数比较
                    3'b100: aluOP=4'b0100;  // xor 异或运算
                    3'b101:
                    begin
                        if (dis==0)
                            aluOP=4'b1000;  // srl 右移指令
                        else
                            aluOP=4'b1001;  // sra 算术右移指令
                    end
                    3'b110: aluOP=4'b0011;  // or 或运算
                    3'b111: aluOP=4'b0010;  // and 与运算
            endcase                 
            end
            7'b0010011: // I类指令
            begin
                pcs=2'b00;
                rwe=1'b1;
                mwe=1'b0;
                mm=3'b0;
                isimm=1'b1;
                is20=1'b0;
                isfpc=1'b0;
                isfm=1'b0;
                ispc4=1'b0;
                case(func)
                    3'b000: aluOP=4'b0000;      // addi 加法
                    3'b010: aluOP=4'b0101;      // slti 有符号数比较
                    3'b011: aluOP=4'b0110;      // sltiu 无符号数比较
                    3'b100: aluOP=4'b0100;      // xori 异或运算
                    3'b110: aluOP=4'b0011;      // ori 或运算
                    3'b111: aluOP=4'b0010;      // andi 与运算
                    3'b001: aluOP=4'b0111;      // slli 左移指令
                    3'b101: 
                        begin
                            if (dis==0)
                                aluOP=4'b1000;  // srli 右移指令
                            else 
                                aluOP=4'b1001;  // srai 循环右移指令
                        end
                    default:;
                endcase     
            end  
            7'b0000011:  // I类:load指令
            begin
                pcs=2'b00;
                rwe=1'b1;
                mwe=1'b0;
                isimm=1'b1;
                is20=1'b0;
                isfpc=1'b0;
                isfm=1'b1;
                ispc4=1'b0;
                aluOP=4'b0;
                case(func)
                    3'b000: mm=3'b000; // lb 取内存低8位,符号拓展成32位
                    3'b001: mm=3'b001; // lh 取内存低16位,符号拓展成32位
                    3'b010: mm=3'b100; // lw 取内存32位
                    3'b100: mm=3'b010; // lbu 取内存低8位,零拓展成32位
                    3'b101: mm=3'b011; // lhu 取内存低16位,零拓展成32位
                    default:;
                endcase     
            end
            7'b0100011: // S类指令
            begin
                pcs=2'b00;
                rwe=1'b0;
                mwe=1'b1;
                isimm=1'b1;
                is20=1'b0;
                isfpc=1'b0;
                isfm=1'b0;
                ispc4=1'b0;
                aluOP=4'b0;
                case(func)
                    3'b000: mm=3'b101; // sb 取寄存器rs2中低8位,存放到对应内存
                    3'b001: mm=3'b110; // sh 取寄存器rs2中低16位,存放到对应内存
                    3'b010: mm=3'b111; // sw 取寄存器rs2中的数,存放到对应内存
                    default:;
                endcase     
            end     
            7'b0110111: // lui指令 将20位立即数保存到寄存器rd的高20位
            begin 
                pcs=2'b00;
                rwe=1'b1;
                mwe=1'b0;
                mm=3'b0;
                isimm=1'b1;
                is20=1'b1;
                isfpc=1'b0;
                isfm=1'b0;
                ispc4=1'b0;
                aluOP=4'b1010;
            end          
            7'b0010111: // auipc指令 将20位立即数左移12位加上PC值保存到寄存器rd中
            begin 
                pcs=2'b00;
                rwe=1'b1;
                mwe=1'b0;
                mm=3'b0;
                isimm=1'b1;
                is20=1'b1;
                isfpc=1'b1;
                isfm=1'b0;
                ispc4=1'b0;
                aluOP=4'b1011;
            end  
            7'b1100111: // jalr指令
            begin 
                pcs=2'b11;
                rwe=1'b1;
                mwe=1'b0;
                mm=3'b0;
                isimm=1'b1;
                is20=1'b0;
                isfpc=1'b0;
                isfm=1'b0;
                ispc4=1'b1;
                aluOP=4'b0;
            end   
            7'b1101111: // jal指令
            begin 
                pcs=2'b10;
                rwe=1'b1;
                mwe=1'b0;
                mm=3'b0;
                isimm=1'b1;
                is20=1'b1;
                isfpc=1'b0;
                isfm=1'b0;
                ispc4=1'b1;
                aluOP=4'b1100;
            end  
            7'b1100011: // B类指令
            begin
                pcs=c?2'b01:2'b00;
                rwe=1'b0;
                mwe=1'b0;
                mm=3'b0;
                isimm=1'b0;
                is20=1'b0;
                isfpc=1'b0;
                isfm=1'b0;
                ispc4=1'b0;
                case(func)
                    3'b000: aluOP=4'b0001;  // beq == 跳转
                    3'b001: aluOP=4'b1101;  // bne != 跳转
                    3'b100: aluOP=4'b0101;  // blt < 跳转
                    3'b101: aluOP=4'b1110;  // bge >= 跳转
                    3'b110: aluOP=4'b0110;  // bltu < 跳转(无符号数)
                    3'b111: aluOP=4'b1111;  // bgeu >= 跳转(无符号数)
                endcase                     
            end                                                        
        endcase
     end

//initial
//    begin
//        $monitor($time,,"CU Input: opcode=%h, func=%h, dis=%h, c=%h", opcode, func, dis, c);
//        $monitor($time,,"CU Output: pcs=%h, rwe=%h, mwe=%h, mm=%h, aluOP=%h, isimm=%h, is20=%h, isfpc=%h, isfm=%h, ispc4=%h",pcs,rwe,mwe,mm,aluOP,isimm,is20,isfpc,isfm,ispc4);
//    end
endmodule

RegFiles.v

module RegFiles(
    input clk,
    input [4:0] raddr1,
    output [31:0] rdata1,
    input [4:0] raddr2,
    output [31:0] rdata2,
    input [4:0] waddr,
    input we,
    input [31:0] wdata
    );
    reg[31:0] regs[1:31];
    
    assign rdata1=(raddr1==5'b00000)?32'b0:regs[raddr1];
    assign rdata2=(raddr2==5'b00000)?32'b0:regs[raddr2];
                      
     always @(posedge clk)
        if(we)
            if(waddr!=4'b00000)
                regs[waddr]<=wdata;
    
//initial
//    begin
//        $monitor($time,,"REG Input: raddr1=%h, raddr2=%h, waddr=%h, wdata=%h, we=%h", raddr1, raddr2, waddr, wdata, we);
//        $monitor($time,,"REG Output: rdata1=%h, rdata2=%h",rdata1,rdata2);
//    end

endmodule

ALU.v

module ALU(
    input [31:0] a,
    input [31:0] b,
    input [3:0] op,
    output [31:0] f,
    output reg c           //判断条件是否满足
    );
    reg[31:0] res;
    
    always @(*)
    begin
        case(op)
            4'b0000:    
            begin
                res=a+b; 
                c=1'b0;
            end
            4'b0001:
            begin    
                res=a-b;
                if (res==0)
                    c=1'b1;
                else
                    c=1'b0;
            end
            4'b0010:    
                begin
                    res=a&b;
                    c=1'b0;
                end
            4'b0011:    
                begin   
                    res=a|b;
                    c=1'b0;
                end
            4'b0100:    
            begin
                res=a^b;
                c=1'b0;
            end
            4'b0101:
                if (($signed(a))<($signed(b)))
                begin
                    res=32'b1;
                    c=1'b1;
                end
                else
                begin
                    res=32'b0;
                    c=1'b0;
                end
            4'b0110: 
                if (a<b)
                begin
                    res=32'b1;
                    c=1'b1;
                end
                else
                begin
                    res=32'b0;
                    c=1'b0;
                end
            4'b0111:
                begin    
                    res=a<<b[4:0];
                    c=1'b0;
                end
            4'b1000:    
                begin
                    res=a>>b[4:0];
                    c=1'b0;
                end
            4'b1001:    
                begin
                    res=($signed(a))>>>b[4:0];
                    c=1'b0;
                end
            4'b1010:    
                begin
                    res=b<<12;
                    c=1'b0;
                end
            4'b1011:    
                begin
                    res=(b<<12)+a;
                    c=1'b0;
                end
            4'b1100: 
                begin  
                    res=(b<<1)+a;
                    c=1'b0;
                end
            4'b1101:
                if (a!=b)
                    c=1'b1;
                else
                    c=1'b0;
            4'b1110:
                if (($signed(a))>=($signed(b)))
                    c=1'b1;
                else
                    c=1'b0;
            4'b1111:
                if(a>=b)
                    c=1'b1;
                else
                    c=1'b0;
        endcase
    end
    assign  f=res;
    
//initial
//    begin
//        $monitor($time,,"ALU Input: a=%h, b=%h, op=%h",a, b, op);
//        $monitor($time,,"ALU Output: f=%h, c=%h",f, c);
//    end
endmodule

NEWRAM.v

module NEWRAM(
    input [5:0] maddr,
    input [31:0] mwdata,
    input clk,
    input we,
    input [2:0] mm,
    output [31:0] mdata
    );
    wire [31:0] tmp,tmp_b,tmp_h,tmp_bu,tmp_hu;
    wire [31:0] tmp_mwdata;
    dataRAM dr(.a(maddr),.d(tmp_mwdata),.clk(clk),.we(we),.spo(tmp));
    wire lb,lh,lw,lbu,lhu,sb,sh,sw;
    // 识别出各类读写方法
    assign lb=~(|mm);               // 000
    assign lh=~(|mm[2:1])&mm[0];    // 001
    assign lw=mm[2]&~(|mm[1:0]);    // 100
    assign lbu=~mm[2]&mm[1]&~mm[0]; // 010
    assign lhu=~mm[2]&(&mm[1:0]);   // 011
    assign sb=mm[2]&~mm[1]&mm[0];   // 101
    assign sh=(&mm[2:1])&~mm[0];    // 110
    assign sw=&mm;                  // 111
    // 读数据
    assign tmp_b={{24{tmp[7]}},tmp[7:0]};
    assign tmp_h={{16{tmp[15]}},tmp[15:0]};
    assign tmp_bu={24'b0,tmp[7:0]};
    assign tmp_hu={16'b0,tmp[15:0]};
    assign mdata={32{lb}}&tmp_b|
                 {32{lh}}&tmp_h|
                 {32{lw}}&tmp|
                 {32{lbu}}&tmp_bu|
                 {32{lhu}}&tmp_hu;
     // 写数据
     assign tmp_mwdata={32{sb}}&{24'b0, mwdata[7:0]}|
                       {32{sh}}&{16'b0, mwdata[15:0]}|
                       {32{sw}}&mwdata;
// initial
//     begin
//         $monitor($time,,"RAM Input: maddr=%h, mwdata=%h, we=%h, mm=%h",maddr, mwdata, we, mm);
//         $monitor($time,,"RAM Temp:tmp_mwdata=%h, tmp=%h", tmp_mwdata, tmp);
//         $monitor($time,,"RAM Output: mdata=%h",mdata);
//     end
endmodule

show.v

module show(
    input clk,
    input rst,
    input [11:0] result,
    output reg[2:0] an,
    output [6:0] out
    );
    wire clk_new;
    div mydiv(.clk(clk),.clk_new(clk_new));
    reg[3:0] data;
    reg[1:0] cur_state,nex_state;
    // 状态转移
    always @(posedge clk)
//    always @(posedge clk_new)
    begin
    if (rst)
        cur_state<=2'b00;
    else
        cur_state<=nex_state;
    end
    // 状态转移条件
    always @(*)
    begin
        case(cur_state)
            2'b00:
                nex_state<=2'b01;
            2'b01:
                nex_state<=2'b10;
            2'b10:
                nex_state<=2'b00;
        endcase
    end
    // 状态输出
    always @(posedge clk)
//    always @(posedge clk_new)
    begin
        case(cur_state)
            2'b00:
            begin
                an<=3'b01;
                data<=result[3:0];
            end
            2'b01:
            begin
                an<=3'b010;
                data<=result[7:4];
            end
            2'b10:
            begin
                an<=3'b100;
                data<=result[11:8];
            end
        endcase
    end
    seven myseven(.data(data),.out(out));        
endmodule

div.v

module div(
    input clk,
    output clk_new
    );
    reg[17:0] q = 18'b0;
    always @(posedge clk)
    begin
        q=q+1'b1;
    end
    assign clk_new=q[17];
endmodule

seven.v

module seven(
    input [3:0] data,
    output reg[6:0] out
    );
  always @(*)
    case (data)
        4'b0000:out = 7'b1111110; // 7e
        4'b0001:out = 7'b0110000; // 30
        4'b0010:out = 7'b1101101; // 6d
        4'b0011:out = 7'b1111001; // 79
        4'b0100:out = 7'b0110011; // 33
        4'b0101:out = 7'b1011011; // 5b
        4'b0110:out = 7'b1011111; // 5f
        4'b0111:out = 7'b1110000; // 70
        4'b1000:out = 7'b1111111; // 7f
        4'b1001:out = 7'b1111011; // 7b
        4'b1010:out = 7'b1110111; // 77
        4'b1011:out = 7'b0011111; // 1f
        4'b1100:out = 7'b1001110; // 4e
        4'b1101:out = 7'b0111101; // 3d
        4'b1110:out = 7'b1001111; // 4f
        4'b1111:out = 7'b1000111; // 47
        default:out = 7'b1111110; //7e
    endcase     
endmodule

四、仿真程序

mysim.v

module mysim(

    );
    /*********定义数据类型,输入数据用reg类型,
    输出数据用wire类型***********/
    reg clk=1'b0;
    reg[3:0] n=4'b1111;
    reg rst=1'b0;
    wire[2:0] an;
    wire[6:0] out;
    /*********为每个输入变量产生测试数据*******/
    always #5
        clk=~clk;            
    initial
    begin
        #4 rst=1'b1;
        #2 rst=1'b0;
    end       
    /*********用上面定义的输入输出数据
    来对测试模块实例化***********/
    top mytop(.clk(clk),.rst(rst),.n(n),.an(an),.out(out));
endmodule

五、仿真结果

请添加图片描述

六、实验结果

请添加图片描述

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

计算机组成原理实验——五、单周期CPU设计 的相关文章

  • PRBS笔记

    1 概述 PRBS 伪随机二进制序列 也称为伪随机码 通常被用来测试高速信号的信号质量 伪随机 也说明了该码流并不是真正的随机 而是具有特性属性 码流由 多项式 决定 具有重复周期 PRBS具有多种阶数 如PRBS7 PRBS15 PRBS
  • STM32【复习串口】

    串口复习加深理解笔记 杂谈 USART FLAG TXE发送缓冲区空标志 说明可以往数据寄存器写入数据了 但并不代码数据发送完成了 USART FLAG TC发送完成标志 这个才是代表USART在缓冲区的数据发送完成了 即从机接收到了数据
  • 数字芯片流程

    芯片设计分为前端设计和后端设计 前端设计 逻辑设计 和后端设计 物理设计 并没有同意严格的界限 这个过程中涉及到了与工艺有关的设计就是后端设计 一 需求分析 产品需要解决的问题 预测3 5年的趋向和走势 确保前瞻性 确保芯片是有卖点的 客户
  • 基于单光子探测的多脉冲周期符合远距离测距

    激光测距技术通过发射主动激光信号对目标进行探测 接收由目标漫反射回来的回波信号并进行统计 处理及换算 从而得到目标的距离 速度信息 实现对目标距离信息的探测 凭借其系统简单 操作灵活 高精度等特点 被广泛运用于民用 科研及军事等各类场合 基
  • FPGA零基础学习之Vivado-UART驱动教程

    FPGA零基础学习之Vivado UART驱动教程 本系列将带来FPGA的系统性学习 从最基本的数字电路基础开始 最详细操作步骤 最直白的言语描述 手把手的 傻瓜式 讲解 让电子 信息 通信类专业学生 初入职场小白及打算进阶提升的职业开发者
  • SD卡读写实验(SPI模式)

    对于 SD 卡的 SPI 模式而言 采用的 SPI 的通信模式为模式 3 即 CPOL 1 CPHA 1 在 SD 卡 2 0 版 本协议中 SPI CLK 时钟频率可达 50Mhz SD 卡的 SPI 模式 只用到了 SDIO D3 SP
  • 手把手教你Modelsim仿真【2020.4版本】

    首先新建一个文件夹 test5 打开Modelsim 依次选择 File gt Change Directory 把目录选择到创建的 test5 文件夹 创建库 依次选择 File gt New gt Library 一般我们选择第三个 库
  • verilog中wire和reg类型的区别

    module counter parameter CNT MAX 25 d24 999 999 input wire sys clk input wire sys rst n output reg led out reg 24 0 cnt
  • 最详细的Vivado安装教程

    V i v a d o 安 装
  • 跨时钟域处理方法(一)——打拍

    一 说明 处理跨时钟域的数据可以分为单bit数据和多bit数据 而打拍的方法主要常见于处理单bit数据的跨时钟域问题 打拍的本质是通过添加寄存器 对输入的数据进行延拍 其主要目标是消除亚稳态的影响 常见的是打2拍 也就是添加2级寄存器 二
  • 握手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
  • FPGA提示产生latch的报错

    在fpga的设计中有时会遇到 latch 的报错 1 latch是什么 Latch 就是锁存器 是一种在异步电路系统中 对输入信号电平敏感的单元 用来存储信息 锁存器在数据锁存使能时 数据被锁存 输入信号不起作用 这违背了组合逻辑中输出随输
  • 八、RISC-V SoC外设——GPIO接口 代码讲解

    前几篇博文中注释了RISC V的内核CPU部分 从这篇开始来介绍RISC V SoC的外设部分 另外 在最后一个章节中会上传额外添加详细注释的工程代码 完全开源 如有需要可自行下载 目录 0 RISC V SoC注解系列文章目录 1 结构
  • 吃透Chisel语言.18.Chisel模块详解(五)——Chisel中使用Verilog模块

    Chisel模块详解 五 Chisel中使用Verilog模块 上一篇文章讲述了用函数实现轻量级模块的方法 可以大幅度提升编码效率 Chisel中也提供了一些好用的函数 方便我们编写代码 也方便Chisel编译器优化生成的硬件电路 在Chi
  • TestBench编写_激励产生

    TestBench编写 激励产生 TestBench编写 激励产生 基本背景 读取函数介绍 a fopen函数使用 b fread函数使用 c fclose函数使用 实际使用 TestBench编写 激励产生 基本背景 最近遇到项目中需要对
  • Verilog HDL——Modelsim仿真

    常用testbench语法 finish 和 stop finish任务用于终止仿真并跳出仿真器 stop任务则用于中止仿真 timescale time unit time precision time unit指定计时和延时的测量单位
  • [从零开始学习FPGA编程-28]:进阶篇 - 基本组合电路-奇偶校验生成器(Verilog语言版本)

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 目录 第1章 奇偶校验生成器 1 1 什么是奇校验 1 2 Verilog语言描述
  • 基于FPGA的AHT10传感器温湿度读取

    文章目录 一 系统框架 二 i2c接口 三 i2c控制模块 状态机设计 状态转移图 START INIT CHECK INIT IDLE TRIGGER WAIT READ 代码 四 数据处理模块 串口 代码 五 仿真 testbench设
  • 基于FPGA的简易BPSK和QPSK

    1 框图 2 顶层 3 m generator M序列的生成 输出速率为500Kbps 4 S2P是串并转换模块 将1bit的m序列转换到50M时钟下的2bit M序列数据 就有4个象限 5 my pll是生成256M的时钟作为载波 因为s
  • Vivado ILA的debug信息保存与读取

    保存 write hw ila data D Project FPGA ILA Debug Data 202401041115 ila upload hw ila data hw ila 1 读取 display hw ila data r

随机推荐

  • dataframe的索引遍历_pandas

    今天是pandas数据处理专题第三篇文章 我们来聊聊DataFrame中的索引 上篇文章当中我们简单介绍了一下DataFrame这个数据结构的一些常见的用法 从整体上大概了解了一下这个数据结构 今天这一篇我们将会深入其中索引相关的应用方法
  • 开发一个APP需要多少钱?

    作为一个移动端开发人员 我们可能被外行朋友或者被客户问及最多的一个问题就是 开发一个APP需要多少钱 不错 这个是大家特别关心的问题 也是互联网公司非常重视的一个问题 因为涉及到自己的成本问题 作为APP开发人员 站在产品经理的角度来给大家
  • windows 2008 32位IIS 服务器转到64位后的各种错误,以及解决方法

    之前在32位IIS服务器上没有问题 发布到64位出现各种错误 请检查以下几项 因各系统不一样 有则检查 无则跳过 重点第4点 1 先安装IIS 后安装 net 4 0环境 否则要重新注册iis windir Microsoft NET Fr
  • 机器学习可视化:模型评估和参数调优

    本篇文章详细阐述机器学习模型评估和参数调优 将主要围绕两个问题来阐述 知其所以然 当你选择的一个机器学习模型运行时 你要知道它是如何工作的 青出于蓝 更进一步 你得知道如何让此机器学习模型工作的更优 模型评估的方法 一般情况来说 F1评分或
  • 第四届蓝桥杯省赛JavaB组第六题三部排序

    标题 三部排序 一般的排序有许多经典算法 如快速排序 希尔排序等 但实际应用时 经常会或多或少有一些特殊的要求 我们没必要套用那些经典算法 可以根据实际情况建立更好的解法 比如 对一个整型数组中的数字进行分类排序 使得负数都靠左端 正数都靠
  • 在阿里云上运行hadoop遇到的50070,9000无法访问问题

    问题 我在阿里云上运行namenode和腾讯云上运行datanode 在hadooop配置完之后 运行hdfs 发现没有namenode 然后查看namenode的日志 日志显示50070端口被占用 9000端口拒绝服务 但是通过natst
  • vue - 实现页面全屏文字水印效果,类似 word 插入的自定义水印(支持单页或整个项目全部页面 “选择性“ 插入,可自定义水印文字、大小样式等,也能动态设置文字)和页面一同渲染,无任何卡顿示例源码

    效果图 代码干净简洁 示例源码注释详细 无任何乱七八糟的代码 本文实现了 单页或整个项目所有页面的全屏水印效果 支持自定义水印文字 可 动态 设置文字内容 你只需要复制本文提供的封装方法 直接在页面中或 App vue 中引入即可生效 只需
  • vue3+element-plus实现表格多选功能(可以清除选项或分页保留选项)

    如图所示 在实际开发中 数据量大的表格基本都添加上了分页功能 每个页面请求的数据回交换更新 第一页的选中效果在跳转至第二页后 如果没有做相关处理 选中项会被清空 具体解决方法如下 在需要处理的表格标签中加上 row key getRowKe
  • 第五章-CSRF漏洞

    第五章 CSRF漏洞 第一节 CSRF原理介绍 1 1 CSRF漏洞定义 CSRF Cross site request forery 跨站请求伪造 也被称为One Click Attack或者Session Riding 通常缩写为CSR
  • k8s组件理解

    一 k8s组件交互关系由下图可大致体现 二 k8s master组件理解 1 kube apiserver组件 kube apiserver Kubernetes kubernets API server 提供了k8s各类资源对象的增删改查
  • EasyTalking微博系统

    EasyTalking微博系统 摘要 随着互联网的迅猛发展 人们的日常生活 学习工作已经离不开网络 人们的生活和工作在未来的生活中将越来越依赖于计算机网络技术的发展 越来越网络化 电子化 虚拟化 便捷化 Internet目前的应用历程和发展
  • 如何const定义一个不可变数组

    有个常见的面试题 我们知道 const是es6中新增用于定义常量 但是对于引用类型来说 const 所说的常量 是指 对应的指针或者说地址是常量 那么 如果我们要求 我们定义的数组里面的元素也是不可改变的呢 先来看现象 const a 1
  • webgl--attribute相关使用

    attribute 是存储限定符 是专门用于向外部导出与点位相关的对象的 这类似于es6模板语法中export vec4 是变量类型 vec4是4维矢量对象 a position 是变量名 之后在js中会根据这个变量名导入变量 这个变量名是
  • [CTSC2008]网络管理Network【树状数组+主席树】

    题目链接 题意 有一棵N个点的树 每个点有对应的权值 现在有这样的操作 0 a b 将a点的权值改成为b k a b 询问a到b的链上第k大的权值是几 我们可以用dfs序的树上差分的方式来解决这个问题 可以发现 求u到v的信息 其实就是求u
  • 【c++】角度与弧度转换

    角度转换为弧度 double angle to radian double degree double min double second double flag degree lt 0 1 0 1 0 判断正负 if degree lt
  • matlab与机器学习(二)程序基本操作(含代码解析)

    备注 之间的为注释内容 注释后面的内容 matlab形成自己的编程风格更有利于简洁的编程界面 图像的初步处理可应用于论文撰写上 文章更有说服力 程序调试有利于发现逻辑问题 都是必备的基础知识 I 清空环境变量及命令 clear all cl
  • Python selenium基础用法详解

    活动地址 CSDN21天学习挑战赛 学习的最大理由是想摆脱平庸 早一天就多一份人生的精彩 迟一天就多一天平庸的困扰 学习日记 目录 学习日记 一 Selenium库介绍 1 Selenium简介 2 Selenium的安装 3 安装浏览器驱
  • RabbitMQ系列(十五)RabbitMQ进阶-SprintBoot集成RabbitMQ使用

    RabbitMQ进阶 SprintBoot集成RabbitMQ使用 文章目录 RabbitMQ进阶 SprintBoot集成RabbitMQ使用 1 构建项目 1 1 Spring Init创建项目 1 2 新建项目包 2 初始化Rabbi
  • 【Chrome】分享几个常用的插件,持续集成

    文章目录 一 准备 打开扩展程序 1 1 方式一 1 2 方式二 1 3 打开开发者模式 二 Chrome应用商店在线安装 需要科学上网 三 离线安装 3 1 离线crx下载地址 3 2 crx方式安装 3 3 加载已解压的扩展程序 方式安
  • 计算机组成原理实验——五、单周期CPU设计

    一 实验目的 掌握指令执行过程的5个阶段 掌握每条指令的数据通路选择 掌握译码器和控制器的功能和实现 掌握数据输入输出处理的方法 实现risc v中RV32I指令的单周期CPU 利用实现的risc v CPU实现平方数 二 实验内容 实现r