当前位置: 首页 > news >正文

黄埭做网站国际外贸网站建设

黄埭做网站,国际外贸网站建设,英文wordpress变中文,非凡网站建设 新三板前言 本篇文章将简单讲解CPU之间各部分的功能及接线#xff0c;并提供Verilog模拟CPU的各个组成部分。该CPU可以完成一些操作#xff0c;如#xff1a;加减法#xff0c;与或#xff0c;指令跳转等#xff0c;最后提供testbench用于测试该CPU的工作情况是否符合预期。 C…前言  本篇文章将简单讲解CPU之间各部分的功能及接线并提供Verilog模拟CPU的各个组成部分。该CPU可以完成一些操作如加减法与或指令跳转等最后提供testbench用于测试该CPU的工作情况是否符合预期。 CPU简单讲解 CPU及相关硬件的作用 Random Access MemoryRAM随机存储寄存器即内存包含所有CPU要处理的数据RAM包含一系列的地址每个地址对应的都是一个二进制数据。CPU一般将会按顺序从RAM中读取数据但实际上是可以以任意顺序访问RAM。当计算机运行时它向RAM发送一个地址以获得那个程序。通常RAM不会有任何操作除非CPU与RAM连线的读使能为高电平。如果读使能为高电平电路导通RAM将返回这个地址的数据给CPU。从此CPU开始处理数据处理完成后它会向RAM发送一个地址并将读使能置高接着获取下一个数据。如果CPU需要向RAM写入数据它将输出一个值和一个地址并将写使能置高将数据写入RAM对应的地址上。RAM的地址上存储的二进制数可能表示一条指令一个数字一个字符一个地址等等。 Instruction SetIS指令集即CPU可以完成指令种类的集合比如两个数相加移动某个数去某个新地址等等。 Control UnitCU控制单元队长它从RAM中接收指令通过解析这个指令变成其他元件可以理解的命令即向其他元件输出控制信号。 Arithmetic Logic UnitALU算术逻辑单元是受控制单元控制的一个元件ALU执行所有的数学运算例如之前提到的加法指令中的加法。ALU有两个输入口inputA和inputB。ALU的工作过程如下CU从RAM收到了指令告诉ALU该做什么运算ALU执行运算并输出结果。除此之外ALU将会对CU输出一个状态标志信号表明当前状态和下一个时钟需要做的事。当CU与寄存器的写使能为高电平的时候ALU输出的结果将会被暂时性的存储到寄存器上。那么如何将寄存器上的数据读出CU实际上也会有个与寄存器的读使能信号连线当它为高电平时寄存器输出该数据。寄存器的输出线路会连在CPU总线上总线是一组连在计算机里多个元件之间的线路。总线上会有更多独立的寄存器Group Registers它们同样通过读使能和写使能与CU相连。它们用于存储刚刚那个寄存器放在总线上的数据。这些组寄存器用于在多个操作间存储数字。 Temporary Register临时寄存器由于总线上同一时间一般只能有一个数据而ALU有两个输入端口这就意味着我们需要先存好一个数据来自于组寄存器中的数据再与总线上的数据来自于组寄存器中的数据进行运算。存放数据提供给ALU的寄存器就叫临时寄存器。需要注意的是临时寄存器不需要和CU有读写使能的连线因为它并不会与总线上的其他寄存器产生冲突。 Instruction RegisterIR指令寄存器用于存放CU从RAM中读到的指令它也不需要和CU有读写使能的连线因为它并不会与总线上的其他寄存器产生冲突。它只会将指令输出给CU基于这个指令CU会告诉ALU执行什么运算。 Instruction Address Register指令地址寄存器在我的Verilog程序里也叫Program CounterPCCPU需要它去了解下一个指令在RAM中的何处在没有“跳转”指令发生的前提下下一条指令所在的地址通常是当前指令的所在地址1但如果发生了跳转则新地址应为上一条指令在RAM中的地址offsetoffset随不同的跳转指令而各不相同是一个变化的值。因为CU并不需要读取PC中的数据仅需要写入一条指令所在的地址因此它们之间只需要有写使能连线而不需要读使能连线。RAM收到PC传递给它的地址后将会将这个地址上的数据传给IR再由IR传给CU。 相关图示 Verilog代码  alu_mux.v module alu_mux (clk, rst, en_in,offset, rd_q,rs_q,alu_in_sel,alu_a,alu_b,en_out );input [15:0] rd_q, rs_q ; input clk, rst, en_in, alu_in_sel ; input [7:0] offset ; output reg [15:0] alu_a, alu_b ; output reg en_out ;always (negedge rst or posedge clk) beginif (rst 1b0) beginalu_a 16b0000_0000_0000_0000 ;alu_b 16b0000_0000_0000_0000 ;en_out 1b0;end else if (en_in 1b1) beginalu_a rd_q;en_out 1b1;if (alu_in_sel 1b0) alu_b {{8{offset[7]}}, offset[7:0]} ; else alu_b rs_q; endelse en_out 1b0;end endmodule/* alu_mux: 用于给alu输入数据若alu_in_sel0则说明只需要一个操作数若alu_in_sel1则需要两个操作数当en_in是能有效时输出使能有效 */ alu.v timescale 1ns / 1psdefine B15to0H 3b000 define AandBH 3b011 define AorBH 3b100 define AaddBH 3b001 define AsubBH 3b010 define leftshift 3b101 define rightshift 3b110module alu (clk, rst, en_in, alu_a, alu_b, alu_func, en_out, alu_out );input [15:0] alu_a, alu_b ; input clk, rst, en_in ; input [2:0] alu_func ; output reg [15:0] alu_out ; output reg en_out ;always (negedge rst or posedge clk) beginif (rst 1b0) beginalu_out 16b0000_0000_0000_0000 ;en_out 1b0 ;end else beginif (en_in 1b1) beginen_out 1b1;case (alu_func)B15to0H: alu_out alu_b ; AandBH: alu_out a b ; AorBH: alu_out a | b ; AaddBH: alu_out a b ; AsubBH: alu_out a - b ; leftshift: alu_out (alu_out 1) ; rightshift: alu_out (alu_out 1) ;default: alu_out alu_out ; endcaseendelse en_out 1b0;endend endmodule/*根据输入alu_func的值确定如何将两个操作数alu_a和alu_b运算得到alu_out */ control_unit.v module control_unit (clk,rst,en,en_alu,en_ram_out,ins,offset_addr,en_ram_in, en_group_pulse,en_pc_pulse,reg_en,alu_in_sel,alu_func,pc_ctrl );/*en: Control_Unit的使能信号en_alu: alu的输出使能信号即用于告诉control unit此时alu有输出en_ram_out: RAM的输出使能信号即用于告诉control unit此时RAM有输出ins: 当前的指令 */ input clk, rst, en, en_alu, en_ram_out ; input [15:0] ins ;/*en_ram_in: RAM输入使能告诉RAM此时有数据输入en_group_pulse: 与datapath同步时钟信号en_pc_pulse: 连datapath的en_pc_pulsealu_in_sel: 连datapath的alu_in_seloffset_addr: 连datapath的offset_addrreg_en: 连datapath的reg_enalu_func: 连datapath的alu_funcpc_ctrl: 连datapath的pc_ctrl */ output en_ram_in, en_group_pulse, en_pc_pulse, alu_in_sel ; output reg [7:0] offset_addr ; output [3:0] reg_en ; output [2:0] alu_func ; output [1:0] pc_ctrl ;wire [15:0] ir_out ; wire en_out ;ir ir1(.clk(clk),.rst(rst),.ins(ins),.en_in(en_ram_out),.en_out(en_out),.ir_out(ir_out));state_transition state_transition1(.clk(clk),.rst(rst),.en_in(en),.en1(en_out),.en2(en_alu),.rd(ir_out[11:10]),.opcode(ir_out[15:12]),.en_fetch_pulse(en_ram_in), .en_group_pulse(en_group_pulse),.en_pc_pulse(en_pc_pulse),.pc_ctrl(pc_ctrl),.reg_en(reg_en),.alu_in_sel(alu_in_sel),.alu_func(alu_func) );always (en_out or ir_out) beginoffset_addr ir_out[7:0] ;endendmodule cpu.v module cpu(clk,rst,en_in,en_ram_out,addr,ins,en_ram_in );input clk, rst ,en_in, en_ram_out ; input [15:0] ins ; output [15:0] addr ; output en_ram_in ;wire en_pc_pulse, en_group_pulse, alu_in_sel, en_alu ; wire [1:0] pc_ctrl ; wire [3:0] reg_en ; wire [2:0] alu_func ; wire [7:0] offset_addr ;data_path data_path1(.clk(clk),.rst(rst),.offset(ins[7:0]),.offset_addr(offset_addr),.en_pc_pulse(en_pc_pulse),.pc_ctrl(pc_ctrl),.en_in(en_group_pulse),.reg_en(reg_en),.rd(ins[11:10]),.rs(ins[9:8]),.alu_in_sel(alu_in_sel),.alu_func(alu_func),.en_out(en_alu),.pc_out(addr) ); control_unit control_unit1(.clk(clk),.rst(rst),.en(en_in),.en_alu(en_alu), .en_ram_out(en_ram_out),.ins(ins),.offset_addr(offset_addr),.en_ram_in(en_ram_in),.en_group_pulse(en_group_pulse),.en_pc_pulse(en_pc_pulse),.reg_en(reg_en),.alu_in_sel(alu_in_sel),.alu_func (alu_func),.pc_ctrl(pc_ctrl) ); endmodule data_path.v module data_path (clk, rst,offset_addr, en_pc_pulse,pc_ctrl, offset, en_in,reg_en, alu_in_sel,alu_func, en_out, pc_out,rd,rs );input clk, rst, en_pc_pulse, en_in, alu_in_sel ; input [7:0] offset_addr, offset ; input [1:0] pc_ctrl, rd, rs ; input [3:0] reg_en ; input [2:0] alu_func ; output en_out ; output [15:0] pc_out ;wire [15:0] rd_q, rs_q, alu_a, alu_b, alu_out ; wire en_out_group, en_out_alu_mux ; pc pc1(clk(clk),rst(rst), en_in(en_pc_pulse),pc_ctrl(pc_ctrl),offset_addr(offset_addr), pc_out(pc_out) );reg_group reg_group1(.clk(clk),.rst(rst),.en_in(en_in),.reg_en(reg_en),.d_in(alu_out),.rd(rd),.rs(rs),.rd_q(rd_q),.en_out(en_out_group),.rs_q(rs_q) );alu_mux alu_mux1( .clk(clk),.rst(rst),.en_in(en_out_group),.rd_q(rd_q),.rs_q(rs_q),.offset(offset),.alu_in_sel(alu_in_sel),.alu_a(alu_a),.en_out(en_out_alu_mux), .alu_b(alu_b) );alu alu1(.clk(clk),.rst(rst),.en_in(en_out_alu_mux), .alu_a(alu_a),.alu_b(alu_b),.alu_func(alu_func),.en_out(en_out),.alu_out(alu_out ) ); endmodule /*datapath包含alualu_mux等模块 */ ir.v module ir(clk,rst,ins,en_in,en_out,ir_out );input clk, rst ; input [15:0] ins ; input en_in ; output reg en_out ; output reg [15:0] ir_out ;always (posedge clk or negedge rst) beginif (!rst) beginir_out 16b000000000000 ;en_out 1b1 ;endelse beginif (en_in) beginen_out 1b1 ;ir_out ins ;endelse en_out 1b0 ;end end endmodule/* IR: Instruction Register, 用于存放当前即将执行的指令在使能有效时将指令输出给state_transition完成状态转移 */pc.v timescale 1ns / 1psmodule pc(clk,rst, en_in,pc_ctrl, // 控制指令寄存器的下一曲值offset_addr, pc_out );input clk, rst, en_in ; input wire [1:0] pc_ctrl ; input wire [7:0] offset_addr ; output reg [15:0] pc_out ;always (posedge clk or negedge rst) beginif (rst 0) pc_out 0 ;else beginif (en_in 1) begincase (pc_ctrl) 2b00: pc_out pc_out ; 2b01: pc_out pc_out 1 ;2b10: pc_out {8b00000000, offset_addr[7:0]} ; // jump去指定的地址2b11: pc_out pc_out offset_addr ; default: pc_out pc_out ;endcaseendendend endmodule/*pc: program counter */ reg_group.v timescale 1ns / 1psmodule reg_group(clk, rst, en_in, reg_en, d_in, rd,rs, en_out, rd_q,rs_q ); input clk, rst, en_in ; // 时钟信号复位信号操作四个寄存器的使能信号 input wire [3:0] reg_en ; // 用于实例化寄存器的使能信号 input wire [15:0] d_in ; // 输入数据 input wire [1:0] rd, rs ; // 用于选择如何分配寄存器的值给两个输出信号两个输出信号均有4种取值共有四个寄存器每个信号读取其中一个寄存器中的值共16种 output reg en_out ; // 输出使能 output reg [15:0] rd_q, rs_q ; // 输出信号 目标寄存器和源寄存器wire [15:0] q0, q1, q2, q3 ; // 每个寄存器的输出register reg0(.clk(clk),.rst(rst),.en(reg_en[0]), .d(d_in), .q(q0) );register reg1(.clk(clk),.rst(rst),.en(reg_en[1]), .d(d_in), .q(q1) );register reg2(.clk(clk),.rst(rst),.en(reg_en[2]), .d (d_in), .q (q2) );register reg3(.clk(clk),.rst(rst),.en(reg_en[3]), .d(d_in), .q(q3) ); always (posedge clk or negedge rst)if (rst 0) beginrd_q 0 ; rs_q 0 ; en_out 0; endelse beginif (en_in 1) beginen_out 1 ; case ({rd[1:0], rs[1:0]})4b0000: beginrd_q q0 ;rs_q q0 ;end4b0001: beginrd_q q0 ;rs_q q1 ;end 4b0010: begin rd_q q0 ; rs_q q2 ; end4b0011: begin rd_q q0; rs_q q3;end 4b0100: begin rd_q q1;rs_q q0;end 4b0101: begin rd_q q1;rs_q q1;end 4b0110: begin rd_q q1;rs_q q2;end 4b0111: begin rd_q q1;rs_q q3;end 4b1000: begin rd_q q2 ;rs_q q0 ;end 4b1001: begin rd_q q2 ; rs_q q1 ; end 4b1010: begin rd_q q2 ;rs_q q2 ;end 4b1011: begin rd_q q2 ;rs_q q3 ;end 4b1100: begin rd_q q3 ;rs_q q0 ;end 4b1101: begin rd_q q3 ; rs_q q1 ; end 4b1110: begin rd_q q3 ;rs_q q2 ;end 4b1111: begin rd_q q3 ;rs_q q3 ;end default: beginrd_q 0 ;rs_q 0 ;endendcaseendelse en_out 0 ;end endmodule /* 在每个时钟上升沿确定如何将哪些寄存器中的值赋给rd_q和rs_qrd_q和rs_q将用于给alu_a和alu_b赋值 */ register.v timescale 1ns / 1psmodule register(clk,rst,en, d, q );input clk, rst, en ; input wire [15:0] d ; output reg [15:0] q ;always (posedge clk or negedge rst) beginif (rst 0) q 0 ;else if (en 1) q d ; else q q ; end endmodule/*寄存器模块在时钟上升沿且Control Unit给出的控制信号en为高时更新寄存器否则锁存数据 */ state_transistion.v module state_transition(clk,rst,en_in,en1,en2,rd,opcode,en_fetch_pulse,en_group_pulse,en_pc_pulse,pc_ctrl,reg_en,alu_in_sel,alu_func );input clk, rst ; input en_in ; // 表示此时有指令需要处理从空闲状态转为取指状态 input en1 ; // 接收指令寄存器的使能只有有指令来临时才会进行状态转移 input en2 ; // 接收alu的输出 input [1:0] rd ; // destination register 目的寄存器 input [3:0] opcode ; // 指令中的操作码不同的操作码对应不同的next_state/*en_ram_in: RAM输入使能告诉RAM此时有数据输入en_group_pulse: 与datapath同步时钟信号en_pc_pulse: 连datapath的en_pc_pulsealu_in_sel: 连datapath的alu_in_selreg_en: 连datapath的reg_enalu_func: 连datapath的alu_funcpc_ctrl: 连datapath的pc_ctrl */ output reg en_fetch_pulse ; output reg en_group_pulse ; output reg en_pc_pulse ; output reg [1:0] pc_ctrl; output reg [3:0] reg_en ; output reg alu_in_sel ; output reg [2:0] alu_func ;reg en_fetch_reg, en_fetch ; reg en_group_reg, en_group ; // group reg的写控制信号和读控制信号 reg en_pc_reg, en_pc ; reg [3:0] current_state, next_state ; parameter Initial 4b0000 ; parameter Fetch 4b0001 ; parameter Decode 4b0010 ; parameter Execute_Moveb 4b0011 ; parameter Execute_Add 4b0100 ; parameter Execute_Sub 4b0101 ; parameter Execute_And 4b0110 ; parameter Execute_Or 4b0111 ; parameter Execute_Jump 4b1000 ; parameter Write_back 4b1001 ;always (posedge clk or negedge rst) begin // 有限状态机的现态与次态的转移if (!rst)current_state Initial ;else current_state next_state ; endalways (current_state or en_in or en1 or en2 or opcode) begincase (current_state)Initial: beginif (en_in)next_state Fetch ;elsenext_state Initial ;endFetch: beginif (en1) next_state Decode ;elsenext_state current_state ;endDecode: begincase (opcode) 4b0000: next_state Execute_Moveb ;4b0010: next_state Execute_Add ;4b0101: next_state Execute_Sub ;4b0111: next_state Execute_And ;4b1001: next_state Execute_Or ;4b1010: next_state Execute_Jump ;default: next_state current_state ;endcaseendExecute_Moveb: beginif (en2) // 如果此时alu确实有数输出证明这个状态完成了next_state Write_back ;elsenext_state current_state ;endExecute_Add: beginif(en2) // 如果此时alu确实有数输出证明这个状态完成了next_state Write_back ;elsenext_state current_state ;endExecute_Sub: beginif(en2) // 如果此时alu确实有数输出证明这个状态完成了next_state Write_back ;elsenext_state current_state ;endExecute_And: beginif(en2) // 如果此时alu确实有数输出证明这个状态完成了next_state Write_back ;elsenext_state current_state ;end Execute_Or: beginif(en2) // 如果此时alu确实有数输出证明这个状态完成了next_state Write_back ;elsenext_state current_state ;end Execute_Jump: next_state Fetch ;Write_back: next_state Fetch ;default: next_state current_state ;endcase end// 用于输出控制信号 always (rst or next_state) beginif (!rst) beginen_fetch 1b0 ;en_group 1b0 ;en_pc 1b0 ;pc_ctrl 2b00 ;reg_en 4b0000 ;alu_in_sel 1b0 ;alu_func 3b000 ;endelse begincase (next_state)Initial: beginen_fetch 1b0 ;en_group 1b0 ;en_pc 1b0 ;pc_ctrl 2b00 ;reg_en 4b0000 ;alu_in_sel 1b0 ;alu_func 3b000 ;endFetch: beginen_fetch 1b1 ; // 此时需要取指en_group 1b0 ;en_pc 1b1 ;pc_ctrl 2b01 ; // 取下一个指令reg_en 4b0000 ; alu_in_sel 1b0 ;alu_func 3b000 ;endDecode: beginen_fetch 1b0 ;en_group 1b0 ;en_pc 1b0 ;pc_ctrl 2b00 ;reg_en 4b0000 ;alu_in_sel 1b0 ;alu_func 3b000 ;endExecute_Moveb: beginen_fetch 1b0 ;en_group 1b1 ;en_pc 1b0 ;pc_ctrl 2b00 ;reg_en 4b0000 ;alu_in_sel 1b0 ;alu_func 3b000 ;endExecute_Add: beginen_fetch 1b0 ;en_group 1b1 ;en_pc 1b0 ;pc_ctrl 2b00 ;reg_en 4b0000 ;alu_in_sel 1b0 ;alu_func 3b001 ;endExecute_Sub: begin// please add your code hereen_fetch 1b0 ;en_group 1b1 ;en_pc 1b0 ;pc_ctrl 2b00 ;reg_en 4b0000 ;alu_in_sel 1b0 ;alu_func 3b001 ;endExecute_And: begin// please add your code hereen_fetch 1b0 ;en_group 1b1 ;en_pc 1b0 ;pc_ctrl 2b00 ;reg_en 4b0000 ;alu_in_sel 1b0 ;alu_func 3b001 ;endExecute_Or: begin// please add your code hereen_fetch 1b0 ;en_group 1b1 ;en_pc 1b0 ;pc_ctrl 2b00 ;reg_en 4b0000 ;alu_in_sel 1b0 ;alu_func 3b001 ;endExecute_Jump: begin// please add your code hereen_fetch 1b0 ;en_group 1b1 ;en_pc 1b0 ;pc_ctrl 2b00 ;reg_en 4b0000 ;alu_in_sel 1b0 ;alu_func 3b001 ;endWrite_back: begincase (rd)2b00: reg_en 4b0001 ;2b01: reg_en 4b0010 ;2b10: reg_en 4b0100 ;2b11: reg_en 4b1000 ;default: reg_en 4b0000 ;endcaseenddefault: beginen_fetch 1b0 ;en_group 1b0 ;en_pc 1b0 ;pc_ctrl 2b00 ;reg_en 4b0000 ;alu_in_sel 1b0 ;alu_func 3b000 ;endendcaseend endalways (posedge clk or negedge rst) beginif (!rst) beginen_fetch_reg 1b0 ;en_pc_reg 1b0 ;en_group_reg 1b0 ;endelse beginen_fetch_reg en_fetch ; en_pc_reg en_pc ;en_group_reg en_group ;end endalways (en_fetch or en_fetch_reg)en_fetch_pulse en_fetch (~en_fetch_reg) ;always (en_pc_reg or en_pc)en_pc_pulse en_pc (~en_pc_reg) ; // 此时需要读入下一个指令且当此时指令寄存器中为空时请求下一条指令always (en_group_reg or en_group)en_group_pulse en_group (~en_group_reg) ;endmodule Testbench timescale 1ns / 1psu(); reg clk,rst,en_in,en_ram_out; reg [15:0] ins; wire en_ram_in; wire [15:0] addr;cpu test_cpu(.clk (clk),.rst (rst),.en_in (en_in),.en_ram_in (en_ram_in), .ins (ins), .en_ram_out (en_ram_out),.addr (addr) );parameter Tclk 10;initial begin//define clkendinitial begin//define rst endinitial begin //define en_in and en_ram_out endinitial begin//define ins ,you can assign 0000_0000_0000_0001//0000_0100_0000_0010 and so on to ins.endinitial begin#(Tclk*400) $stop; endendmodule如有疑问欢迎打扰。
http://www.zqtcl.cn/news/825284/

相关文章:

  • 做外贸英语要什么网站网站整体设计风格
  • 高端网站开发哪里好2022最新新闻素材摘抄
  • 网站建设实训个人深圳做营销网站的公司哪家好
  • 广州seo网站策划wordpress关闭主题提示
  • 做门票售卖网站怎么制作自己的水印
  • 网站绑定两个域名怎么做跳转asp 网站后台
  • 百度网站怎么做的赚钱吗郑州资助app下载
  • 成都成华区网站建设天津网站优
  • 大朗网站制作商城网站建设相关费用
  • 付费阅读网站代码搜索引擎推广方式有哪些
  • 企业网站搭建介绍一个电影的网站模板下载
  • wordpress网站插件下载郑州专业网站制作
  • 佛山南海区建网站的公司dw怎么做购物网站
  • 杭州网站关键词排名优化响应式网站好还是自适应网站好
  • 潍坊作风建设网站什么是网站建设技术
  • 网站后台图片不显示东莞市企业招聘信息网
  • 网站发布平台商业网站的网址
  • 免费的培训网站建设门户网站建设管理工作方案
  • 企业网站建设实验感想企业网络推广哪家公司好
  • 网站建设和维护视频如何入侵网站服务器
  • 怎样建设网站空间成都网站设公司
  • 百度文库账号登录入口百度seo规则最新
  • 服务器可以自己的网站吗网络营销策划与创意
  • 广州市招投标网站个人网站可以做论坛
  • 易语言做购物网站春节网站怎么做
  • 建公司网站设计网站公司做网上夫妻去哪个网站
  • 稷山网站建设wordpress单本小说采集
  • 凡客网站规划与建设ppt网站做跳转教程
  • 怎么看网站空间多大做网站旅游销售
  • 天津做手机网站建设旅游网站的目的