微程序控制器(Verilog HDL虚拟实验)

微程序控制器

一、什么是微程序控制器?

微程序控制器是一种控制器,同组合逻辑控制器相比较,具有规整性、灵活性、可维护性等一系列优点,因而在计算机设计中逐渐取代了早期采用的组合逻辑控制器,并已被广泛地应用。在计算机系统中,微程序设计技术是利用软件方法来设计硬件的一门技术 。

二、设计简单的微程序控制器

信息流设计:

1615—1098—765—43—0
F0:BM (1位)F1:NA(6位)F2:D/S(1位)F3:XXoe(两位)F4:PSW(1位)F5:XXce (2位)F6:ALU(4位)
0:固定转移下一位地址0:DST0:NOP0:NOP0:NOP0:NOP
1:多分支转移1:SRC1:GRSoe1:PSWce1:GRSce1:ADD
2:RFoe2:RFce2:SUB
3:DATAoe3:RXce3:AND
4:OR
5:XOR

方案(1)采用指令译码为

微地址BMNAD/SXXoePSWXXceALUop
00H10000000000000000
  • 在uprogram.txt中,将该微指令写入,具体格式如下
@00 10000000000000000

LD微指令设计如下:

微地址BMNAD/SXXoePSWXXceALUop
3CH00000000110010000
  • 在uprogram.txt中,将此微指令写入,格式如下
@3C 00000000110010000
  • MOV指令设计(供参考)
微地址BMNAD/SXXoePSWXXceALUop
00H00000011010110000
01H00000100001100000
02H00000000100010000
  • 加法指令设计
微地址BMNAD/SXXoePSWXXceALUop
04H00001010010110000
05H00001101011100001
06H00000000100010000
  • 减法指令设计
微地址BMNAD/SXXoePSWXXceALUop
08H00010010010110000
09H00010101011100010
0AH00000000100010000
  • &指令设计
微地址BMNAD/SXXoePSWXXceALUop
0CH00011010010110000
0DH00011101011100011
0EH00000000100010000
  • OR指令设计
微地址BMNAD/SXXoePSWXXceALUop
10H00100010010110000
11H00100101011100100
12H00000000100010000
  • XOR指令设计
微地址BMNAD/SXXoePSWXXceALUop
14H00101010010110000
15H0101101011100101
16H00000000100010000

各模块代码:

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)采用指令译码为

微地址BMNAD/SXXoePSWXXceALUop
3FH11111110000000000
  • 在uprogram.txt中,将该微指令写入,具体格式如下
@3FH 11111110000000000
  • LD微指令设计如下:
微地址BMNAD/SXXoePSWXXceALUop
3CH01111110110010000

在uprogram.txt中,将此微指令写入,格式如下

@3C 01111110110010000
  • 加法指令设计
微地址BMNAD/SXXoePSWXXceALUop
04H00001010010110000
05H00001101011100001
06H01111110100010000
  • 减法指令设计
微地址BMNAD/SXXoePSWXXceALUop
08H00010010010110000
09H00010101011100010
0AH01111110100010000
  • &指令设计
微地址BMNAD/SXXoePSWXXceALUop
0CH00011010010110000
0DH00011101011100011
0EH01111110100010000
  • OR指令设计
微地址BMNAD/SXXoePSWXXceALUop
10H00100010010110000
11H00100101011100100
12H01111110100010000
  • XOR指令设计
微地址BMNAD/SXXoePSWXXceALUop
14H00101010010110000
15H00101101011100101
16H01111110100010000
  • MOV指令
微地址BMNAD/SXXoePSWXXceALUop
00H00000011010110000
01H00000100001100000
02H01111110100010000
  • 算数右移指令
微地址BMNAD/SXXoePSWXXceALUop
18H00110010010110000
19H00110100001100110
1AH01111110100010000
  • 左移指令
微地址BMNAD/SXXoePSWXXceALUop
1CH00111010010110000
1DH00111100001100111
1EH01111110100010000
  • 逻辑非指令
微地址BMNAD/SXXoePSWXXceALUop
20H01000010010110000
21H01000100001101000
22H01111110100010000
  • 加1指令
微地址BMNAD/SXXoePSWXXceALUop
24H01001010010110000
25H01001100001101001
26H01111110100010000
  • 减1指令
微地址BMNAD/SXXoePSWXXceALUop
28H01010010010110000
29H01010100001101010
2AH01111110100010000
  • 带进位加法
微地址BMNAD/SXXoePSWXXceALUop
2CH01011010010110000
2DH01011101011101011
2EH01111110100010000
  • 带借位减法
微地址BMNAD/SXXoePSWXXceALUop
30H01100010010110000
31H01100101011101100
32H01111110100010000

方案而与上述已给出的模块不同之处,仅在于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.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Best-Wishes

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值