微程序控制器
一、什么是微程序控制器?
微程序控制器是一种控制器,同组合逻辑控制器 相比较,具有规整性、灵活性、可维护性 等一系列优点,因而在计算机设计中逐渐取代了早期采用的组合逻辑控制器,并已被广泛地应用。在计算机系统 中,微程序设计 技术是利用软件方法来设计硬件的一门技术 。
二、设计简单的微程序控制器
信息流设计:
16 15—10 9 8—7 6 5—4 3—0 F0:BM (1位) F1:NA(6位) F2:D/S(1位) F3:XXoe(两位) F4:PSW(1位) F5:XXce (2位) F6:ALU(4位) 0:固定转移 下一位地址 0:DST 0:NOP 0:NOP 0:NOP 0:NOP 1:多分支转移 1:SRC 1:GRSoe 1:PSWce 1:GRSce 1:ADD 2:RFoe 2:RFce 2:SUB 3:DATAoe 3:RXce 3:AND 4:OR 5:XOR
方案(1)采用指令译码为
微地址 BM NA D/S XXoe PSW XXce ALUop 00H 1 000000 0 00 0 00 0000
LD微指令设计如下:
微地址 BM NA D/S XXoe PSW XXce ALUop 3CH 0 000000 0 11 0 01 0000
微地址 BM NA D/S XXoe PSW XXce ALUop 00H 0 000001 1 01 0 11 0000 01H 0 000010 0 00 1 10 0000 02H 0 000000 0 10 0 01 0000
微地址 BM NA D/S XXoe PSW XXce ALUop 04H 0 000101 0 01 0 11 0000 05H 0 000110 1 01 1 10 0001 06H 0 000000 0 10 0 01 0000
微地址 BM NA D/S XXoe PSW XXce ALUop 08H 0 001001 0 01 0 11 0000 09H 0 001010 1 01 1 10 0010 0AH 0 000000 0 10 0 01 0000
微地址 BM NA D/S XXoe PSW XXce ALUop 0CH 0 001101 0 01 0 11 0000 0DH 0 001110 1 01 1 10 0011 0EH 0 000000 0 10 0 01 0000
微地址 BM NA D/S XXoe PSW XXce ALUop 10H 0 010001 0 01 0 11 0000 11H 0 010010 1 01 1 10 0100 12H 0 000000 0 10 0 01 0000
微地址 BM NA D/S XXoe PSW XXce ALUop 14H 0 010101 0 01 0 11 0000 15H 0 10110 1 01 1 10 0101 16H 0 000000 0 10 0 01 0000
各模块代码:
uAG模块(微地址形成)
module uAG
(
output logic [5:0] uAGOut,
input logic [3:0] OPCODE,
input logic [5:0] NA,
input logic BM
);
always@(BM)
begin
if(BM ==0 )
uAGOut =NA;
else if(BM ==1)
uAGOut[5:0] = {OPCODE,{2'b00}};
end
endmodule
uAR模块(微地址寄存器)
module uAR
#(parameter N = 6)
( output reg [N-1:0] oQ,
input wire [N-1:0] iD,
input wire Clk,
input wire Reset
);
always @(posedge Clk or posedge Reset)
begin
if (Reset)
oQ = {N{1'b0}};
else
oQ = iD;
end
endmodule
Virtualboard模块(顶层)
`default_nettype none
module VirtualBoard (
input logic CLOCK, // 10 MHz Input Clock
input logic [19:0] PB, // 20 Push Buttons, logical 1 when pressed
input logic [35:0] S, // 36 Switches
output logic [35:0] L, // 36 LEDs, drive logical 1 to light up
output logic [7:0] SD7, // 8 common anode Seven-segment Display
output logic [7:0] SD6,
output logic [7:0] SD5,
output logic [7:0] SD4,
output logic [7:0] SD3,
output logic [7:0] SD2,
output logic [7:0] SD1,
output logic [7:0] SD0
);
/********* Seven-segment decoder instantiation **********/
logic [3:0] HD[7:0]; // 8 hexadecimal display
SevenSegDecode ssdecode_inst7(.iData(HD[7]), .oSeg(SD7));
SevenSegDecode ssdecode_inst6(.iData(HD[6]), .oSeg(SD6));
SevenSegDecode ssdecode_inst5(.iData(HD[5]), .oSeg(SD5));
SevenSegDecode ssdecode_inst4(.iData(HD[4]), .oSeg(SD4));
SevenSegDecode ssdecode_inst3(.iData(HD[3]), .oSeg(SD3));
SevenSegDecode ssdecode_inst2(.iData(HD[2]), .oSeg(SD2));
SevenSegDecode ssdecode_inst1(.iData(HD[1]), .oSeg(SD1));
SevenSegDecode ssdecode_inst0(.iData(HD[0]), .oSeg(SD0));
/************** The declaration of signals **************/
wire reset;
wire clk;
wire [3:0] BUS, RX_Q, F, RF_Q, GRS_Q;
wire [3:0] FLAG, PSW_Q;
wire [3:0] ALUop;
wire GRSce, RXce, RFce, PSWce;
wire DATAoe, GRSoe, RFoe;
wire SRC;
wire [3:0] DATA;
wire [1:0] index, Rs, Rd;
wire [3:0] OPCODE;
wire [5:0] uAR_Q, next_addr;
wire [16:0] uI;
wire [5:0] uAG_Out;
wire branch_mode;
/** The input port is replaced with an internal signal **/
assign reset = PB[0];
assign clk = PB[1];
assign DATA = S[3:0];
assign Rs = S[1:0];
assign Rd = S[5:4];
assign OPCODE = S[9:6];
/************* The logic of this experiment *************/
//微地址形成
uAG uAG_inst(.uAGOut(uAG_Out), .OPCODE(OPCODE), .NA(next_addr), .BM(branch_mode));
//微地址寄存器
uAR #(6) uAR_inst(.oQ(uAR_Q), .iD(uAG_Out), .Clk(clk), .Reset(reset));
//控制存储器
ROM CM(.iAddress(uAR_Q), .oData(uI));
//微指令译码
wire NOP1, NOP2;
assign branch_mode = uI[16];
assign next_addr = uI[15:10];
assign SRC = uI[9];
assign {DATAoe, RFoe, GRSoe, NOP2} = 2**uI[8:7];
assign PSWce = uI[6];
assign {RXce, RFce, GRSce, NOP1} = 2**uI[5:4];
assign ALUop = uI[3:0];
//运算器数据通路
ALU #(4) ALU_inst(.iOp(ALUop), .iX(RX_Q), .iY(BUS), .oF(F), .oFlag(FLAG), .Cin(PSW_Q[0]));
assign index = SRC ? Rs : Rd;
GRS #(4) GRS_inst(.iD(BUS), .oQ (GRS_Q), .Load(GRSce), .Clk(clk), .Index(index));
DataReg #(4) RX_inst(.oQ(RX_Q), .iD(BUS), .Clk(clk), .Load(RXce), .Reset(reset));
DataReg #(4) RF_inst(.oQ(RF_Q), .iD(F), .Clk(clk), .Load(1'b1), .Reset(reset));
DataReg #(4) PSW_inst(.oQ(PSW_Q), .iD(FLAG), .Clk(clk), .Load(PSWce ), .Reset(reset));
assign BUS = RFoe ? RF_Q : 4'bzzzz;
assign BUS = GRSoe ? GRS_Q : 4'bzzzz;
assign BUS = DATAoe ? DATA : 4'bzzzz;
/****** Internal signal assignment to output port *******/
assign HD[7] = {2'b00,next_addr[5:4]};
assign HD[6] = next_addr[3:0];
assign HD[5] = RX_Q;
assign HD[4] = BUS;
assign HD[3] = GRS_Q;
assign HD[2] = DATA;
assign HD[1] = RF_Q;
assign HD[0] = F;
assign L[35:30] = uAG_Out[5:0];
assign L[29:24] = uAR_Q[5:0];
assign L[23:20] = PSW_Q;
assign L[19:18] = index;
assign L[17] = DATAoe;
assign L[16] = GRSoe;
assign L[15] = RFoe;
assign L[14] = GRSce;
assign L[13] = RXce;
assign L[12] = PSWce;
assign L[11] = RFce;
assign L[10] = SRC;
assign L[4] = branch_mode;
assign L[3:0] = ALUop;
endmodule
ROM模块
module ROM (
input wire [5:0] iAddress,
output wire [16:0] oData
);
reg [16:0] mem[63:0];
assign oData = mem[iAddress];
initial
$readmemb("uprogram.txt",mem);
endmodule
GRS、DataReg模块请参考我之前的博文:点我参考
方案(2)采用指令译码为
微地址 BM NA D/S XXoe PSW XXce ALUop 3FH 1 111111 0 00 0 00 0000
微地址 BM NA D/S XXoe PSW XXce ALUop 3CH 0 111111 0 11 0 01 0000
在uprogram.txt中,将此微指令写入,格式如下
微地址 BM NA D/S XXoe PSW XXce ALUop 04H 0 000101 0 01 0 11 0000 05H 0 000110 1 01 1 10 0001 06H 0 111111 0 10 0 01 0000
微地址 BM NA D/S XXoe PSW XXce ALUop 08H 0 001001 0 01 0 11 0000 09H 0 001010 1 01 1 10 0010 0AH 0 111111 0 10 0 01 0000
微地址 BM NA D/S XXoe PSW XXce ALUop 0CH 0 001101 0 01 0 11 0000 0DH 0 001110 1 01 1 10 0011 0EH 0 111111 0 10 0 01 0000
微地址 BM NA D/S XXoe PSW XXce ALUop 10H 0 010001 0 01 0 11 0000 11H 0 010010 1 01 1 10 0100 12H 0 111111 0 10 0 01 0000
微地址 BM NA D/S XXoe PSW XXce ALUop 14H 0 010101 0 01 0 11 0000 15H 0 010110 1 01 1 10 0101 16H 0 111111 0 10 0 01 0000
微地址 BM NA D/S XXoe PSW XXce ALUop 00H 0 000001 1 01 0 11 0000 01H 0 000010 0 00 1 10 0000 02H 0 111111 0 10 0 01 0000
微地址 BM NA D/S XXoe PSW XXce ALUop 18H 0 011001 0 01 0 11 0000 19H 0 011010 0 00 1 10 0110 1AH 0 111111 0 10 0 01 0000
微地址 BM NA D/S XXoe PSW XXce ALUop 1CH 0 011101 0 01 0 11 0000 1DH 0 011110 0 00 1 10 0111 1EH 0 111111 0 10 0 01 0000
微地址 BM NA D/S XXoe PSW XXce ALUop 20H 0 100001 0 01 0 11 0000 21H 0 100010 0 00 1 10 1000 22H 0 111111 0 10 0 01 0000
微地址 BM NA D/S XXoe PSW XXce ALUop 24H 0 100101 0 01 0 11 0000 25H 0 100110 0 00 1 10 1001 26H 0 111111 0 10 0 01 0000
微地址 BM NA D/S XXoe PSW XXce ALUop 28H 0 101001 0 01 0 11 0000 29H 0 101010 0 00 1 10 1010 2AH 0 111111 0 10 0 01 0000
微地址 BM NA D/S XXoe PSW XXce ALUop 2CH 0 101101 0 01 0 11 0000 2DH 0 101110 1 01 1 10 1011 2EH 0 111111 0 10 0 01 0000
微地址 BM NA D/S XXoe PSW XXce ALUop 30H 0 110001 0 01 0 11 0000 31H 0 110010 1 01 1 10 1100 32H 0 111111 0 10 0 01 0000
方案而与上述已给出的模块不同之处,仅在于uAR模块(微地址寄存器)
该方案应采用如下方法,供读者参考:
module uAR
#(parameter N = 6)
( output reg [N-1:0] oQ,
input wire [N-1:0] iD,
input wire Clk,
input wire Reset
);
always @(posedge Clk or posedge Reset)
begin
if (Reset)
oQ = {N{1'b1}};
else
oQ = iD;
end
endmodule
See the Pen Snake Game by moPsych (@moPsych ) on CodePen .
er; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title=“Snake Game”> See the Pen Snake Game by moPsych (@moPsych ) on CodePen .