硬布线控制(Verilog HDL虚拟实验)

硬布线控制

一、何为硬布线?

硬布线控制器是早期计算机设计方法之一。硬布线把控制部件看作产生专门固定时序控制信号的逻辑电路,而此逻辑电路以使用最少元件和取得最高操作速度作为设计目标。

值得注意的是,一旦控制部件构成后,除非重新设计和物理上对它重新布线,否则要想增加新的控制功能是不可能的。这种逻辑电路是一种由门电路和触发器构成的复杂树形逻辑网路,故称之为硬布线控制器。

系统时钟
时序信号发生器
与或逻辑阵列
时序控制信号
IR
指令译码
CPU内部控制信号
系统总线控制信号
PSW

13—1211—109—87—43—0
RDRS1RS2DATAOPCODE
指令类型指令助记符OPCODE功能
R型add rd, rs1, rs20001rd⬅(rs1)+(rs2)
sub rd,rs1,rs20010rd⬅(rs1)-(rs2)
and rd, rs1, rs20011rd⬅(rs1)∧(rs2)
or rd, rs1, rs20100rd⬅(rs1)∨(rs2)
xor rd, rs1, rs20101rd⬅(rs1)⊕(rs2)
I型addi rd,rs1,#data1001rd⬅(rs1)+data
subi rd,rs1,#data1010rd⬅(rs1)-data
andi rd,rs1,#data1011rd⬅(rs1)∧data
ori rd,rs1,#data1100rd⬅(rs1)∨data
xori rd,rs1,#data1101rd⬅(rs1)⊕data

二、顶层模块

`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 input port is replaced with an internal signal **/
wire reset  = PB[0];
wire clk    = PB[1];
wire [1:0] write_addr = S[13:12];
wire [1:0] read_addr1 = S[11:10];
wire [1:0] read_addr2 = S[9:8];
wire [3:0] imm_data = S[7:4];
wire [3:0] opcode = S[3:0];

//各模块间连线信号
wire [3:0] alu_result, alu_y, read_data1, read_data2;
wire [3:0] flag;
wire write_enable;
wire immToALU;
wire [3:0] ALUctrl;

/************* The logic of this experiment *************/
assign write_enable =1'b1;
assign immToALU = opcode[3];
always@(opcode[2:0])
begin
 case(opcode[2:0])
  3'b001:ALUctrl = 4'b0001;
  3'b010:ALUctrl = 4'b0010;
  3'b011:ALUctrl = 4'b0011;
  3'b100:ALUctrl = 4'b0100;
  3'b101:ALUctrl = 4'b0101;
  endcase
 end
RegFile #(4)RegFile_ins(.Data(alu_result),.oQ1(read_data1),.oQ2(read_data2),.iWE(write_enable),.clk(clk),.WIndex(write_addr),.RIndex1(read_addr1),.RIndex2(read_addr2));
  // 数据通路部分
assign alu_y = immToALU ? imm_data : read_data2;

ALU #(4)ALU_inst(.iOp(ALUctrl),.iX(read_data1),.iY(alu_y),.oF(alu_result),.oFlag(flag));


/****** Internal signal assignment to output port *******/
assign HD[0] = alu_y;
assign HD[1] = read_data1;
assign HD[2] = read_data2;
assign HD[3] = alu_result;
assign L[21:18] = flag;
assign L[5] = write_enable;
assign L[4] = immToALU;
assign L[3:0] = ALUctrl;

endmodule

RegFile模块

module RegFile
#(parameter N = 4)
(
	input logic [N-1:0] Data,
	output logic [N-1:0] oQ1,
	output logic [N-1:0] oQ2,
	input logic iWE,
	input logic clk,
	input logic [1:0] WIndex,
	input logic [1:0] RIndex1,
	input logic [1:0] RIndex2
);
logic load3, load2, load1, load0;
always @ (posedge clk or posedge iWE)
begin
    if (iWE)
        case (WIndex)
            2'b00: {load3, load2, load1, load0} = 4'b0001;
            2'b01: {load3, load2, load1, load0} = 4'b0010;
			2'b10: {load3, load2, load1, load0} = 4'b0100;
			2'b11: {load3, load2, load1, load0} = 4'b1000;
            default: {load3, load2, load1, load0} = 4'bx;
        endcase
    else
        {load3, load2, load1, load0} = 4'b0000;
end

logic [N-1:0] R0_Q, R1_Q, R2_Q, R3_Q;
DataReg #(N) R0(.oQ(R0_Q), .iD(Data), .Clk(clk), .Load(load0), .Reset(1'b1));
DataReg #(N) R1(.oQ(R1_Q), .iD(Data), .Clk(clk), .Load(load1), .Reset(1'b0));
DataReg #(N) R2(.oQ(R2_Q), .iD(Data), .Clk(clk), .Load(load2), .Reset(1'b0));
DataReg #(N) R3(.oQ(R3_Q), .iD(Data), .Clk(clk), .Load(load3), .Reset(1'b0));

always @ *
begin
	case (RIndex1)
		2'b00: oQ1 = R0_Q;
		2'b01: oQ1 = R1_Q;
		2'b10: oQ1 = R2_Q;
		2'b11: oQ1 = R3_Q;
	endcase
	case (RIndex2)
		2'b00: oQ2 = R0_Q;
		2'b01: oQ2 = R1_Q;
		2'b10: oQ2 = R2_Q;
		2'b11: oQ2 = R3_Q;
	endcase
end

endmodule

ALU模块

module ALU
#(parameter N=4)
(
input logic [N-1:0]iOp,
input logic Cin,
input logic [N-1:0] iX,
input logic [N-1:0] iY ,
output logic [N-1:0] oF,
output logic [N-1:0] oFlag
);
wire [N-1:0]M;
logic [N:0]result;
wire SR;
wire SV;
wire SL;
wire [1:0]SW;


wire [N-1:0] A,B;
wire C0;
always@(iOp[N-1:0])
 begin
  case(iOp[N-1:0])  //F=X;
   4'b0000:begin
	 SW[1:0]=2'b00;  //11
	 M[3:0]=4'b0000;
	 SV=1'b1;
	 
	 SR=1'b0;
	 SL=1'b0;
     end
	4'b0001: begin  //F=X+Y
	 SW[1:0]=2'b00;
	 M[3:0]=4'b0001;
	 SV=1'b1;
	 SR=1'b0;
	 SL=1'b0;
	        end
	4'b0010: begin	//F=X-Y 
	   SW[1:0]=2'b00;
      SV=1'b1;
      M[3:0]=4'b0110;
      SR=1'b0;
	   SL=1'b0;		
				end
	4'b0011:begin     //F=X &Y
	     SV=1'b1;
		  SW[1:0]=2'b01;
		  M[3:0]=4'b0001;
		  SR=1'b0;
		  SL=1'b0;
		  end
	4'b0100:begin   // F=X or Y
	    SV=1'b1;
		 SW[1:0]=2'b10;
		 M[3:0]=4'b0001;
		 SR=1'b0;
		 SL=1'b0;
		 end
	4'b0101:begin       //F=X ^Y
	   SV=1'b1;
		SW[1:0]=2'b11;
		M[3:0]=4'b0001;
		SL=1'b0;
		SR=1'b0;
		end
	  endcase
	  end
	 
assign C0 =(Cin & M[3] | M[2]);
wire sign, zero, overflow, carryOut;
assign A[3]=SR & iX[3] | iX[3] & SV | SL &iX[2] ;
assign A[2]=SR & iX[3] | iX[2] & SV | SL &iX[1];
assign A[1]=SR & iX[2] | iX[1] & SV | SL &iX[0] ;
assign A[0]=SR & iX[1] | iX[0] & SV | SL &1'b0 ;
assign B[3] =(M[0] & iY[3]) | (M[1] & !iY[3]) ;
assign B[2] =M[0] & iY[2] | M[1] & !iY[2] ;
assign B[1] =M[0] & iY[1] | M[1] & !iY[1] ;
assign B[0] =M[0] & iY[0] | M[1] & !iY[0] ;


always_comb
 begin 
  case({SW[1:0]})
   2'b00: result=A+B+C0;
	2'b01: result=iX & B;
	2'b10: result=iX |B;
	2'b11: result=iX ^ B;
	default:begin
	if(SV==0 & SR==0 & SL==0)
	result={(5){1'bZ}};
	end
	endcase
end

assign carryOut=result[4];
assign oF[3:0] = result[3:0];  
assign sign = oF[3];
always@( SV,SR,SL)
begin
if(SV==0 & SR==0 & SL==0)
 zero=0;
 else
 zero = (oF==0) ? 1 : 0;  // ~|F;
end
assign overflow = (~A[3]) & ~B[3] & oF[3] | (A[3]) & B[3] & ~oF[3] ;


assign oFlag={sign, zero, overflow, carryOut};
endmodule
  • 4
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Best-Wishes

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

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

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

打赏作者

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

抵扣说明:

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

余额充值