Verilog MIPS32 CPU(八)-- 控制器
- Verilog MIPS32 CPU(一)-- PC寄存器
- Verilog MIPS32 CPU(二)-- Regfiles
- Verilog MIPS32 CPU(三)-- ALU
- Verilog MIPS32 CPU(四)-- RAM
- Verilog MIPS32 CPU(五)-- CP0
- Verilog MIPS32 CPU(六)-- MDU
- Verilog MIPS32 CPU(七)-- DIV、DIVU
- Verilog MIPS32 CPU(八)-- 控制器
module CtrlUnit(
input [:] instr,
input [:] rdata1, rdata2,
input [:] pc,ram_data,hi,lo,alu_r,cop_data,mul_out,
input [:] exc_addr,
input clk,
output mtc0,eret,teq_exc,
output reg [:] mdu,
output reg reg_wena,
output ram_wena,
output reg [:] cause,
output [:] rs,rt,rd,waddr,
output reg [:] wdata,reg_data,
output [:] ram_addr,
output reg [:] pc_in,
output reg [:] alu_a,alu_b,
output reg [:] alu_op
);
//******MIPS-55*********//
parameter //SPECIAL OP LIST 5-0
ADDU = 'b100001,
SUBU = 'b100011,
ADD = 'b100000,
SUB = 'b100010,
AND = 'b100100,
OR = 'b100101,
XOR = 'b100110,
NOR = 'b100111,
SLT = 'b101010,
SLTU = 'b101011,
SRL = 'b000010,
SRA = 'b000011,
SLL = 'b000000,
SLLV = 'b000100,
SRLV = 'b000110,
SRAV = 'b000111,
JR = 'b001000,
JALR = 'b001001,
MULT = 'b011000,
MULTU = 'b011001,
DIV = 'b011010,
DIVU = 'b011011,
MFHI = 'b010000,
MFLO = 'b010010,
MTHI = 'b010001,
MTLO = 'b010011,
BREAK = 'b001101,
SYSCALL = 'b001100,
TEQ = 'b110100,
//SPECIAL 2 func
CLZ = 'b100000,
MUL = 'b000010,
//REGIMM OP LIST 20-16
BLTZ = 'b00000,
BGEZ = 'b00001,
//COP0 OP LIST
ERET = 'b011000, //5-0&&25TH=1
MFC0 = 'b00000, //20-16
MTC0 = 'b00100,
//OPCODE FIELD 31-26
ADDI = 'b001000,
ADDIU = 'b001001,
ANDI = 'b001100,
ORI = 'b001101,
XORI = 'b001110,
LW = 'b100011,
SW = 'b101011,
BEQ = 'b000100,
BNE = 'b000101,
BLEZ = 'b000110,
BGTZ = 'b000111,
SLTI = 'b001010,
SLTIU = 'b001011,
LUI = 'b001111,
J = 'b000010,
JAL = 'b000011,
LB = 'b100000,// Load Byte Function=6'h24
LBU = 'b100100,// 1Load Byte Unsigned
LH = 'b100001,// Load high
LHU = 'b100101,// Load High Unsigned
SB = 'b101000,// Send Byte
SH = 'b101001,// Send High
SPECIAL = 'b000000,
SPECIAL2= 'b011100,
REGIMM = 'b000001,
COP0 = 'b010000;
//ALU OPCODE
parameter _ADDU = 'b0000; //r=a+b unsigned
parameter _ADD = 'b0010; //r=a+b signed
parameter _SUBU = 'b0001; //r=a-b unsigned
parameter _SUB = 'b0011; //r=a-b signed
parameter _AND = 'b0100; //r=a&b
parameter _OR = 'b0101; //r=a|b
parameter _XOR = 'b0110; //r=a^b
parameter _NOR = 'b0111; //r=~(a|b)
parameter _LUI = 'b1000; //r={b[15:0],16'b0}
parameter _SLT = 'b1011; //r=(a-b<0)?1:0 signed
parameter _SLTU = 'b1010; //r=(a-b<0)?1:0 unsigned
parameter _SRA = 'b1100; //r=b>>>a
parameter _SLL = 'b1110; //r=b<<a
parameter _SRL = 'b1101; //r=b>>a
parameter _SYSCALL= 'b1000,
_BREAK = 'b1001,
_TEQ = 'b1101;
wire [:] op = instr[:];
assign rs = instr[:];
assign rt = instr[:];
assign rd = instr[:];
wire [:] func = instr[:];
wire [:] shamt = instr[:];
wire [:] imm = instr[:];
wire [:] addr = instr[:];
parameter SIGN = 'b1;
parameter UNSIGN = 'b0;
wire imm_sign = (op==ANDI||op==ORI||op==XORI)?UNSIGN:SIGN;
wire [:] shamt_ext = {'b0,shamt};
wire [:] imm_ext = imm_sign?{{(){imm[]}},imm}:{'b0,imm};
reg [:] load_data,clz_data;
assign waddr = (op==SPECIAL||op==SPECIAL2)? rd: (op==JAL) ?'b11111:rt;
always@(*)begin
case(op)
SB: reg_data = {'b0,rdata2[7:0]};
SH: reg_data = {'b0,rdata2[15:0]};
SW: reg_data = rdata2;
default:reg_data = rdata2;
endcase
case(op)
LB: load_data = {{{ram_data[]}},ram_data[:]};
LBU: load_data = {'b0,ram_data[7:0]};
LH: load_data = {{{ram_data[]}},ram_data[:]};
LHU: load_data = {'b0,ram_data[15:0]};
LW: load_data = ram_data;
default:load_data = ram_data;
endcase
if(op==SPECIAL)
case(func)
SYSCALL:cause = _SYSCALL;
BREAK: cause = _BREAK;
TEQ: cause = _TEQ;
default:cause = 'b0;
endcase
else cause = 'b0;
/*
1 mult
2 multu
3 div
4 divu
5 mthi
6 mtlo
7 mul
*/
if(op==SPECIAL)
case(func)
MULT: mdu = 'h1;
MULTU: mdu = 'h2;
DIV: mdu = 'h3;
DIVU: mdu = 'h4;
MTHI: mdu = 'h5;
MTLO: mdu = 'h6;
default:mdu = 'h0;
endcase
else mdu = 'h0;
end
wire [:] npc = pc+;
wire [:] pc_branch = npc + {{(){imm[]}},imm,'b00};
wire [:] pc_jmp = {npc[:],addr,'b00};
assign ram_addr = rdata1 + imm_ext;
assign eret = op==COP0 && func==ERET;
wire mfc0 = op==COP0 && rs==MFC0;
assign mtc0 = op==COP0 && rs==MTC0;
assign teq_exc = rdata1==rdata2;
parameter ENA = 'b1;
parameter DIS = 'b0;
wire mem_load = op==LB || op==LH || op==LBU || op==LHU || op==LW;
assign ram_wena = op==SW || op==SH || op==SB;
integer i;
always@(*)begin
case(op)
SPECIAL: case(func)
MULTU,
DIV,
DIVU,
JR,
MTHI,
MTLO,
BREAK,
SYSCALL:reg_wena = DIS;
default:reg_wena = ENA;
endcase
COP0: reg_wena = rs==MFC0?ENA:DIS;
SPECIAL2,
LB,
LBU,
LH,
LHU,
ADDI,
ADDIU,
ANDI,
ORI,
XORI,
LW,
SLTI,
SLTIU,
LUI,
JAL: reg_wena = ENA;
default: reg_wena = DIS;
endcase
case(op)
SPECIAL:case(func)
JALR: wdata = npc;
MFHI: wdata = hi;
MFLO: wdata = lo;
default:wdata = alu_r;
endcase
SPECIAL2:begin
if(func==CLZ) casez(rdata1)
'b1???????????????????????????????: wdata = 32'h0;
'b01??????????????????????????????: wdata = 32'h1;
'b001?????????????????????????????: wdata = 32'h2;
'b0001????????????????????????????: wdata = 32'h3;
'b00001???????????????????????????: wdata = 32'h4;
'b000001??????????????????????????: wdata = 32'h5;
'b0000001?????????????????????????: wdata = 32'h6;
'b00000001????????????????????????: wdata = 32'h7;
'b000000001???????????????????????: wdata = 32'h8;
'b0000000001??????????????????????: wdata = 32'h9;
'b00000000001?????????????????????: wdata = 32'ha;
'b000000000001????????????????????: wdata = 32'hb;
'b0000000000001???????????????????: wdata = 32'hc;
'b00000000000001??????????????????: wdata = 32'hd;
'b000000000000001?????????????????: wdata = 32'he;
'b0000000000000001????????????????: wdata = 32'hf;
'b00000000000000001???????????????: wdata = 32'h10;
'b000000000000000001??????????????: wdata = 32'h11;
'b0000000000000000001?????????????: wdata = 32'h12;
'b00000000000000000001????????????: wdata = 32'h13;
'b000000000000000000001???????????: wdata = 32'h14;
'b0000000000000000000001??????????: wdata = 32'h15;
'b00000000000000000000001?????????: wdata = 32'h16;
'b000000000000000000000001????????: wdata = 32'h17;
'b0000000000000000000000001???????: wdata = 32'h18;
'b00000000000000000000000001??????: wdata = 32'h19;
'b000000000000000000000000001?????: wdata = 32'h1a;
'b0000000000000000000000000001????: wdata = 32'h1b;
'b00000000000000000000000000001???: wdata = 32'h1c;
'b000000000000000000000000000001??: wdata = 32'h1d;
'b0000000000000000000000000000001?: wdata = 32'h1e;
'b00000000000000000000000000000001: wdata = 32'h1f;
'b00000000000000000000000000000000: wdata = 32'h20;
endcase
else if(func==MUL) wdata = mul_out;
else wdata = alu_r;
end
JAL: wdata = npc;
LW,LB,LH,LBU,LHU: wdata = load_data;
COP0: if(rs==MFC0) wdata = cop_data;
else wdata = alu_r;
default: wdata = alu_r;
endcase
//Below is OK
case(op)
SPECIAL: case(func)
SLL,
SRL,
SRA:begin
alu_a = shamt_ext;
alu_b = rdata2;
end
default:begin
alu_a = rdata1;
alu_b = rdata2;
end
endcase
ADDI,
ADDIU,
ANDI,
ORI,
XORI,
SLTI,
SLTIU,
LUI:begin
alu_a = rdata1;
alu_b = imm_ext;
end
default:begin
alu_a = rdata1;
alu_b = rdata2;
end
endcase
//PC Source
case(op)
SPECIAL: case(func)
SYSCALL,
TEQ,
BREAK: pc_in = exc_addr;
JALR,
JR: pc_in = rdata1;
default:pc_in = npc;
endcase
COP0: case(func)
ERET: pc_in = exc_addr;
default:pc_in = npc;
endcase
REGIMM: case(rt)
BLTZ:if(rdata1[])
pc_in = pc_branch;
else
pc_in = npc;
BGEZ:if(!rdata1[])
pc_in = pc_branch;
else
pc_in = npc;
default:pc_in = npc;
endcase
J,
JAL: pc_in = pc_jmp;
BEQ:if(rdata1==rdata2)
pc_in = pc_branch;
else pc_in = npc;
BNE:if(rdata1!=rdata2)
pc_in = pc_branch;
else pc_in = npc;
BLEZ:if(rdata1[] || rdata1=='b0)
pc_in = pc_branch;
else pc_in = npc;
BGTZ:if(!rdata1[] && rdata1!='b0)
pc_in = pc_branch;
else pc_in = npc;
default: pc_in = npc;
endcase
case(op)
SPECIAL:case(func)
ADDU: alu_op = _ADDU;
SUBU: alu_op = _SUBU;
ADD: alu_op = _ADD;
SUB: alu_op = _SUB;
AND: alu_op = _AND;
OR: alu_op = _OR;
XOR: alu_op = _XOR;
NOR: alu_op = _NOR;
SLT: alu_op = _SLT;
SRL: alu_op = _SRL;
SLL: alu_op = _SLL;
SRA: alu_op = _SRA;
SLTU: alu_op = _SLTU;
SRLV: alu_op = _SRL;
SLLV: alu_op = _SLL;
SRAV: alu_op = _SRA;
default: alu_op = _ADDU;
endcase
ORI: alu_op = _OR;
XORI: alu_op = _XOR;
BEQ: alu_op = _SUBU;
BNE: alu_op = _SUBU;
ANDI: alu_op = _AND;
ADDIU: alu_op = _ADDU;
ADDI: alu_op = _ADD;
SLTI: alu_op = _SLT;
SLTIU: alu_op = _SLTU;
LUI: alu_op = _LUI;
default: alu_op = _ADDU;
endcase
end
endmodule
Verilog MIPS32 CPU(八)-- 控制器的更多相关文章
- Verilog MIPS32 CPU(六)-- MDU
Verilog MIPS32 CPU(一)-- PC寄存器 Verilog MIPS32 CPU(二)-- Regfiles Verilog MIPS32 CPU(三)-- ALU Verilog M ...
- Verilog MIPS32 CPU(七)-- DIV、DIVU
Verilog MIPS32 CPU(一)-- PC寄存器 Verilog MIPS32 CPU(二)-- Regfiles Verilog MIPS32 CPU(三)-- ALU Verilog M ...
- Verilog MIPS32 CPU(五)-- CP0
Verilog MIPS32 CPU(一)-- PC寄存器 Verilog MIPS32 CPU(二)-- Regfiles Verilog MIPS32 CPU(三)-- ALU Verilog M ...
- Verilog MIPS32 CPU(四)-- RAM
Verilog MIPS32 CPU(一)-- PC寄存器 Verilog MIPS32 CPU(二)-- Regfiles Verilog MIPS32 CPU(三)-- ALU Verilog M ...
- Verilog MIPS32 CPU(三)-- ALU
Verilog MIPS32 CPU(一)-- PC寄存器 Verilog MIPS32 CPU(二)-- Regfiles Verilog MIPS32 CPU(三)-- ALU Verilog M ...
- Verilog MIPS32 CPU(二)-- Regfiles
Verilog MIPS32 CPU(一)-- PC寄存器 Verilog MIPS32 CPU(二)-- Regfiles Verilog MIPS32 CPU(三)-- ALU Verilog M ...
- Verilog MIPS32 CPU(一)-- PC寄存器
Verilog MIPS32 CPU(一)-- PC寄存器 Verilog MIPS32 CPU(二)-- Regfiles Verilog MIPS32 CPU(三)-- ALU Verilog M ...
- Verilog MIPS32 CPU(九)-- 顶层文件
`timescale 1ns / 1ps /////////////////////////////////////////////////////////////////////////////// ...
- 是否有必要学习使用纯Verilog写一个SDRAM控制器
在做这个SDRAM控制器之前,博主有一个疑问,对于学生来说,是否有必要学习用纯Verilog写一个SDRAM控制器?因为目前X家和A家都有了DDR IP Core,对于要实现一个应用可以直接调用IP ...
随机推荐
- Vim配置:在win10下用vim编译运行C/C++(异步插件管理,一键运行)
为什么用Vim 重新调配vim,追求尽量简单些. 安装 官网下载 PC: MS-DOS and MS-Windows下的 For modern MS-Windows systems (starting ...
- Spring MVC起步
1.1跟踪Spring MVC的请求 每当用户在Web浏览器中点击链接或提交表单的时候,请求就开始工作了.对请求的工作描述就像是快递投送员.与邮局投递员或FedEx投送员一样,请求会将信息从一个地方带 ...
- C# Data Parse
一.DateTime 方法一:Convert.ToDateTime(string) string格式有要求,必须是yyyy-MM-dd hh:mm:ss 方法二:Convert.ToDateTime( ...
- 详解Vue2.0生命周期
网上已经有很多关于vue生命周期的文章,我的这篇文章的由来,其实是我对官网上描述的一句话的思考与理解:“el被新创建的vm.$el替换”,所以文章更多的内容可能是在对vue生命周期中“created ...
- jquery中绑定click事件重复执行问题
jquery中单击事件重复多次执行的问题使用如下方式: $('#sub').unbind('click').click(function () { ... });
- iPhone开发随想:rand()还是arc4random()
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://bj007.blog.51cto.com/1701577/544006 今天在iP ...
- java算法 蓝桥杯 洗牌
问题描述 小弱T在闲暇的时候会和室友打扑克,输的人就要负责洗牌.虽然小弱T不怎么会洗牌,但是他却总是输. 渐渐地小弱T发现了一个规律:只要自己洗牌,自己就一定会输.所以小弱T认为自己洗牌不够均匀,就独 ...
- 第一个Django应用程序_part2
一.数据库配置 此文延续第一个Django应用程序_part1. 打开mystic/settings.py.这是一个普通的Python模块,其模块变量表示Django配置 默认情况下,配置使用SQLi ...
- Cloud Foundry技术资料汇总
来自:http://cnblog.cloudfoundry.com/2012/05/ 本文是Cloud Foundry的一个简单上手指南和资料汇总,内容将根据产品的发布定期更新. Cloud Foun ...
- Paradox
克己博伦 当一个无法阻挡的力量,碰到了一个无法移动的物体?如果这个力量移动了物体,那么这个物体就不是无法移动的.如果这个力量没有移动物体,那么这个无法阻挡的力量就被挡了下来. 上帝能造出一个重到他自己 ...