计算机组成原理实验——五、单周期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设计 的相关文章

  • 【Xilinx Vivado时序分析/约束系列6】FPGA开发时序分析/约束-IO时序输入延时

    目录 源同步FPGA输入时序分析的模型 input delay约束 极限input delay 往期系列博客 源同步FPGA输入时序分析的模型 以下为源同步FPGA输入时序分析的模型的示意图 在之前的文章中介绍过 在此介绍一下各个时钟延时的
  • 数字IC手撕代码-兆易创新笔试真题

    前言 本专栏旨在记录高频笔面试手撕代码题 以备数字前端秋招 本专栏所有文章提供原理分析 代码及波形 所有代码均经过本人验证 目录如下 1 数字IC手撕代码 分频器 任意偶数分频 2 数字IC手撕代码 分频器 任意奇数分频 3 数字IC手撕代
  • 8x8LED点阵

    点量这个只需要把9高电平 13低电平就可以了 共阳极点阵 行线是led的正极 列线是led的列线 左上角点亮 显示多个灯是动态扫描的 一个一个显示的 然后间隔速度要快就可以造成显示 点阵由两篇74Hc595级联在一起驱动的 只需要三个io口
  • Verilog实例-AMBA(AHB)协议

    目录 一 简介 1 1 AHB 1 2 signal list 1 3 Bus interconnection 总线互联 1 4 Overview of AMBA AHB operation 1 4 1 Basic transfer 1 4
  • 【FPGA入门】第八篇、FPGA驱动VGA实现动态图像移动

    目录 第一部分 实现效果 第二部分 动态VGA显示的原理 1 将动态显示的区域提前进行赋值 2 图像块的移动是每张图片叠加后的效果 3 如何实现图像块位置的改变 第三部分 系统结构和驱动波形 1 系统的Top down结构 2 图像块移动的
  • 数码管电子时钟

    文章目录 前言 一 回顾数码管 二 任务描述 三 系统框图 四 模块调用 五 模块原理图 六 工程源码 6 2 时钟计数模块代码 6 2 数码管驱动模块代码 6 3 顶层模块代码 七 仿真测试 7 1 测试代码 7 2 仿真结果 八 管脚信
  • 小梅哥Xilinx FPGA学习笔记9——语法(阻塞与非阻塞赋值)

    阻塞赋值与非阻塞赋值详解 注意 阻塞赋值 1 设计文件 2 激励文件 3 原理图 4 仿真图 非阻塞赋值 1 设计文件 2 激励文件 3 原理图 4 仿真图 注意 阻塞赋值与非阻塞赋值 只有在时序逻辑中才有 不是阻塞赋值 也不是非阻塞赋值
  • TestBench编写_激励产生

    TestBench编写 激励产生 TestBench编写 激励产生 基本背景 读取函数介绍 a fopen函数使用 b fread函数使用 c fclose函数使用 实际使用 TestBench编写 激励产生 基本背景 最近遇到项目中需要对
  • xilinx xdma PCIe中断bug

    xilinx xdma PCIe中断存在bug bug1 此中断虽然是msi或者msx中断 但是不中断cpu bug2 此中断不是边沿中断 而是电平中断 在驱动层需要不断地轮训查询中断事件 bug3 此中断持续时间必须长 而且在收到中断应答
  • 【DDR3 控制器设计】(3)DDR3 的写操作设计

    写在前面 本系列为 DDR3 控制器设计总结 此系列包含 DDR3 控制器相关设计 认识 MIG 初始化 读写操作 FIFO 接口等 通过此系列的学习可以加深对 DDR3 读写时序的理解以及 FIFO 接口设计等 附上汇总博客直达链接 DD
  • PAJ7620U2手势识别——配置0x00寄存器(3)

    文章目录 前言 一 为啥要配置0x00寄存器 二 配置步骤 1 单个读操作步骤图 2 模块状态转移图绘制 3 模块波形图绘制 4 上板验证 5 参考代码 总结 前言 在前面的教程中 小编带领各位读者学习了如何通过I2C协议去唤醒PAJ762
  • 使用七牛云进行文件上传

    目录 一 七牛云入门测试 1 注册七牛云账号 完成后选择对象存储 2 在里面创建空间 一个空间相当于一个文件夹 就是将对象上传到的地方 3 查看个人秘钥 注册完成账号后 会有一个秘钥 上传文件的时候进行授权和认证 4 文件上传测试 二 封装
  • 基于FPGA的AHT10传感器温湿度读取

    文章目录 一 系统框架 二 i2c接口 三 i2c控制模块 状态机设计 状态转移图 START INIT CHECK INIT IDLE TRIGGER WAIT READ 代码 四 数据处理模块 串口 代码 五 仿真 testbench设
  • ALLEGRO等长时如何将PIN DELAY和VIA长度计算在内

    在PCB设计中 对于时序要求严格的线路 Via和IC pin delay的长度必须得到重视 通过下面的操作 可将Via和Pin delay加入到线路长度的计算中 1st 计算Pin delay 打开Constraint Manager 选择
  • 【FPGA】通俗理解从VGA显示到HDMI显示

    注 大部分参考内容来自 征途Pro FPGA Verilog开发实战指南 基于Altera EP4CE10 2021 7 10 上 贴个下载地址 野火FPGA Altera EP4CE10征途开发板 核心板 野火产品资料下载中心 文档 hd
  • 【ZYNQ学习】PL第一课

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

    异步配置信息 跨时钟域 配置信息一般set max delay按照3delay来约束 2 异步回读 rst clear信号 设置set false path 放松时序约束要求 不应分析设计中的逻辑路径 因为不关心点到点时序要求
  • Matlab图像处理系列——图像复原之噪声模型仿真

    微信公众号上线 搜索公众号 小灰灰的FPGA 关注可获取相关源码 定期更新有关FPGA的项目以及开源项目源码 包括但不限于各类检测芯片驱动 低速接口驱动 高速接口驱动 数据信号处理 图像处理以及AXI总线等 本节目录 一 图像复原的模型 二
  • MINI-UTDE 10 BASE-T 集成控制器

    MINI UTDE 10 BASE T 集成控制器 MINI UTDE 10 BASE T 拥有多达三个本地I O板和远程I OS总线通信 为用户提供了一系列生产单元功能的单一控制点 包括诸如夹头 反馈器和辅助机器等外围生产设备 支持所有主
  • ESP10B 锁定连接器

    ESP10B 锁定连接器 ESP10B 电机新增内容包括双极型号标准 NEMA 尺寸 17 23 和 34 的步进电机现在包括输出扭矩范围从 61 盎司英寸到 1291 盎司英寸的双极型号 该电机配有带锁定连接器的尾缆 可轻松连接 每转可步

随机推荐

  • 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