单周期CPU
项目代码
vivado版本为2022.2
链接:
CSDN资源:https://download.csdn.net/download/m0_46314779/85292989
github代码: https://github.com/hd-cmyk/Vivado
实验原理
一共实现了15条指令,9条R型指令,5条I型指令,1条J型指令,指令格式与编码参照《LS-CPU-EXB-003cpu设计与体系结构实验指导手册》中的附录A1。
各个模块核心思路:
PC模块:PC是程序计数器,用于存放下一条要执行指令的地址。有四种情况考虑
① PC=PC+4,执行下一条指令
② PC=PC+4+立即数*4,执行的指令为分支跳转指令,跳转至当前指令后的立即数+1条指令。(考虑了延迟槽技术)
③ PC={(PC+4)[31:28],立即数<<2};,执行的指令为 J型指令,跳转目标为PC 的最高 4 位与立即数左移2 位后的值拼接得到。
④ PC=PC
指令存储器模块:建立异步读的单口ROM 类型的IP核,将指令存入coe文件中供IP核调用。
寄存器堆模块:用二维数组建立两个读端口一个写端口的寄存器堆,并初始化为0。
数据存储器模块:建立二维数据模拟真双口RAM,一个端口用于读写,另一个端口用于将存储器中数据显示在led显示屏上。
控制器模块:针对不同指令中opcode和Func的值设置各个控制变量的值。
MIPS指令
编写冒泡排序程序:
用ADDIU指令将立即数存到寄存器中再用SW指令将寄存器中的数存到存储器中。将8,7,6,5,4,3,2,1八个数存到存储器地址1-8中。写一个循环实现冒泡排序,排序完成后存储器内地址1-8显示1,2,6,7,8,13,14,15。
用汇编指令编写一个冒泡排序,再将汇编指令转化为MIPS指令(下文中G表示通用寄存器)
G[31]存1
G[30]存0
G[1] ax
G[2] bx
G[3] cx
G[4] dx
G[5] si
G[6] cf
00100111110000110000000000001000//mov cx,8 //addiu 3 30 8
00000000011111100000100000100001//mov ax,xc //addu 1 3 30
loop2:
00100111110001010000000000000001//mov si,1// addiu 5 30 1
loop1:
10001100101000100000000000000000//mov bx,[SI] //lw 2 0 5
10001100101001000000000000000001//mov dx,[SI+1]// lw 4 1 5
00000000010001000011000000101010// cmp bx,dx //slt 6 2 4小于置位
00010000110111110000000000000010//je cf=1 next
10101100101001000000000000000000//mov [SI],dx //sw 4 0 5
10101100101000100000000000000001//mov [SI+1],bx//sw 2 1 5
next:
00100100101001010000000000000001//add si,1//addiu 5 5 1
00010100001001011111111111111000//cmp ax,si jnz loop1//bne 1 5 -7
00000000001111110000100000100011//sub ax,1//subu 1 1 31
00010100001111111111111111110101//cmp ax,1 jnz loop2//bne 1 31 -1
rom.coe文件
memory_initialization_radix = 2;
memory_initialization_vector =
00100111110111110000000000000001
00100111110000010000000000001000
10101111110000010000000000000001
00100111110000010000000000000111
10101111110000010000000000000010
00100111110000010000000000000110
10101111110000010000000000000011
00100111110000010000000000000101
10101111110000010000000000000100
00100111110000010000000000000100
10101111110000010000000000000101
00100111110000010000000000000011
10101111110000010000000000000110
00100111110000010000000000000010
10101111110000010000000000000111
00100111110000010000000000000001
10101111110000010000000000001000
00100111110000110000000000001000
00000000011111100000100000100001
00100111110001010000000000000001
10001100101000100000000000000000
10001100101001000000000000000001
00000000010001000011000000101010
00010000110111110000000000000010
10101100101001000000000000000000
10101100101000100000000000000001
00100100101001010000000000000001
00010100001001011111111111111000
00000000001111110000100000100011
00010100001111111111111111110101
11111111111111111111111111111111
代码
顶层模块SingleCycleCPU
module SingleCycleCPU(
input clk,Reset,
input [31:0]test_addr,//取存储器
input [4:0]test_addr1,//取寄存器
output [31:0] test_data,
output [31:0]test_data1
);
wire [31:0] instruction;
wire [31:0]sort;
wire [31:0] addr;
wire [1:0]PCSrc;
wire zero;
wire [31:0]Out1;
wire [31:0]Out2;
wire [4:0]rs;
wire [4:0]rt;
wire [5:0] opCode;
wire [31:0] Result;
wire [4:0] rd;
wire Extsel, Alu_SrcA, Alu_SrcB;
wire RD,WR;
wire [5:0]Func;
wire PCWre;
wire [31:0]extendImm;
wire[3:0] Alu_Op;
wire[31:0] DataOut,DB;
wire[15:0] Imm;
wire[4:0] sa;
wire DBDataSrc, RegWre,RegDst;
assign sort=(opCode==6'b111111)?32'd1:32'd0;
PC ins(
.clk(clk),
.Reset(Reset),
.PCWre(PCWre),
.PCSrc(PCSrc),
.Imm(extendImm),
.addr(addr),
.instruction(instruction)
);
instructionMemory ins1(
.addr({2'b0,addr[31:2]}),
.opCode(opCode),
.rs(rs),
.rt(rt),
.rd(rd),
.immediate(Imm),
.sa(sa),
.Func(Func),
.instruction(instruction)
);
regfile ins2(
.clk(clk),
.RegWre(RegWre),//写使能
.raddr1(rs),//读操作
.raddr2(rt),
.rdata1(Out1),
.rdata2(Out2),
.waddr(RegDst ? rd : rt),//写操作
.wdata(DB),//DB从ALU或者寄存器堆拿出数据
.test_addr(test_addr1),
.test_data(test_data1)
);
Alu ins3(
.Alu_SrcA(Alu_SrcA),
.Alu_SrcB(Alu_SrcB),
.ReadData1(Out1),//操作数1
.ReadData2(Out2),//操作数2
.sa(sa),
.extend(extendImm),
.Alu_Op(Alu_Op),//操作
.zero(zero),
.Alu_Result(Result)//结果
);
SignZeroExtend ins4(
.Imm(Imm),//l型指令低16位是立即数,扩展有1.零扩展 高16为0,2.符号扩展
.Extsel(Extsel),//状态'0',0扩展,否则符号位扩展
.extendImm(extendImm)
);
DataMemory ins5(
.clk(clk),
.wenr(RD),//读使能
.wenw(WR),//写使能
.DBDataSrc(DBDataSrc),//MemtoReg数据保存的选择端,为0来自ALU运算结果的输出,为1来自数据寄存器(Data MEM)的输出
.DAddr(Result),//若为LW指令则DAddr=aluResult
.DataIn(Out2),
.DataOut(DataOut),
.DB(DB),
.test_addr(test_addr),
.test_data(test_data)
);
ControlUnit ins6(
.opCode(opCode),
.zero(zero),
.Func(Func),
.PCWre(PCWre),//=1,PC可变
.AluSrcA(Alu_SrcA),
.AluSrcB(Alu_SrcB),
.DBDataSrc(DBDataSrc),//数据保存的选择端,为0来自ALU运算结果的输出,为1来自数据寄存器(Data MEM)的输出
.RegWre(RegWre),
.mRD(RD),//数据存储器的读使能
.mWR(WR),//数据存储器的写使能
.ExtSel(Extsel),//立即数扩展
.RegDst(RegDst),//写寄存器组寄存器的地址,为0的时候地址来自rt,为1的时候地址来自rd
.PCSrc(PCSrc),//控制PC的
.Alu_Op(Alu_Op)
);
endmodule
display外围模块
module single_display(
//时钟与复位信号
input clk,
input resetn, //后缀"n"代表低电平有效
//触摸屏相关接口,不需要更改
output lcd_rst,
output lcd_cs,
output lcd_rs,
output lcd_wr,
output lcd_rd,
inout[15:0] lcd_data_io,
output lcd_bl_ctr,
inout ct_int,
inout ct_sda,
output ct_scl,
output ct_rstn
);
//-----{LED显示}begin
//-----{LED显示}end
//-----{调用寄存器堆模块}begin
//寄存器堆多增加一个读端口,用于在触摸屏上显示32个寄存器值
wire [31:0] test_addr;//存储器
wire [31:0] test_data;
wire [4:0]test_addr1;//寄存器
wire [31:0]test_data1;
SingleCycleCPU CPU(
.clk (clk ),
.Reset(resetn),
.test_addr(test_addr),
.test_addr1(test_addr1),
.test_data (test_data),
.test_data1(test_data1)
);
//-----{调用寄存器堆模块}end
//---------------------{调用触摸屏模块}begin--------------------//
//-----{实例化触摸屏}begin
//此小节不需要更改
reg display_valid;
reg [39:0] display_name;
reg [31:0] display_value;
wire [5 :0] display_number;
wire input_valid;
wire [31:0] input_value;
lcd_module lcd_module(
.clk (clk ), //10Mhz
.resetn (resetn ),
//调用触摸屏的接口
.display_valid (display_valid ),
.display_name (display_name ),
.display_value (display_value ),
.display_number (display_number),
.input_valid (input_valid ),
.input_value (input_value ),
//lcd触摸屏相关接口,不需要更改
.lcd_rst (lcd_rst ),
.lcd_cs (lcd_cs ),
.lcd_rs (lcd_rs ),
.lcd_wr (lcd_wr ),
.lcd_rd (lcd_rd ),
.lcd_data_io (lcd_data_io ),
.lcd_bl_ctr (lcd_bl_ctr ),
.ct_int (ct_int ),
.ct_sda (ct_sda ),
.ct_scl (ct_scl ),
.ct_rstn (ct_rstn )
);
//-----{实例化触摸屏}end
//-----{从触摸屏获取输入}begin
//根据实际需要输入的数修改此小节,
//建议对每一个数的输入,编写单独一个always块
//32个寄存器显示在7~38号的显示块,故读地址为(display_number-1)
assign test_addr = display_number-6'd1;
//-----{从触摸屏获取输入}end
//-----{输出到触摸屏显示}begin
//根据需要显示的数修改此小节,
//触摸屏上共有44块显示区域,可显示44组32位数据
//44块显示区域从1开始编号,编号为1~44,
always @(posedge clk)
begin
if ( display_number <6'd33 )
begin //块号7~38显示32个通用寄存器的值
display_valid <= 1'b1;
display_name[39:16] <= "MEM";
display_name[15: 8] <= {4'b0011,test_addr[7:4]};
display_name[7 : 0] <= {4'b0011,test_addr[3:0]};
display_value <= test_data;
end
else
begin
display_valid<=1'b0;
display_name<=40'd0;
display_value<=32'd0;
end
end
//-----{输出到触摸屏显示}end
//----------------------{调用触摸屏模块}end---------------------//
endmodule
PC
module PC(
input clk,Reset,//Reset从头开始执行
input PCWre,//PCWre=1可更改,=0不可更改
input [1:0]PCSrc,//=1为分支指令
input [31:0] Imm,//立即数
inout [31:0] instruction,
output reg[31:0] addr
);
initial
begin
addr=0;
end
reg [31:0]addr1;
always@(posedge clk)
begin
if(PCWre)
begin
addr1=addr+4;
if(PCSrc==2'b00) addr=addr+4;//跳转到下一条指令
else if(PCSrc==2'b01) addr=addr+4+Imm*4;//跳转指令
else if(PCSrc==2'b10) addr={addr1[31:28],instruction[25:0]<<2};
else if(PCSrc==2'b11) addr=addr;
end
end
endmodule
instructionMemory
module instructionMemory(
// 根据数据通路图定义输入和输出
input [31:0] addr,
output [5:0] opCode,
output [4:0] rs, rt, rd,
output [15:0] immediate,
output [4:0] sa,
output [5:0] Func,
output [31:0] instruction
);
inst_rom inst_rom_module(
.a (addr[7:0]),
.spo (instruction)
);
// output
assign opCode = instruction[31:26];
assign rs = instruction[25:21];
assign rt = instruction[20:16];
assign rd = instruction[15:11];
assign immediate = instruction[15:0];
assign sa = instruction[10:6];
assign Func=instruction[5:0];
endmodule
Alu模块
module Alu(
input Alu_SrcA,
input Alu_SrcB,
input [31 :0] ReadData1,//操作数1
input [31 :0] ReadData2,//操作数2
input [4:0] sa,
input [31:0] extend,
input [3:0] Alu_Op,//操作
output reg zero,
output reg[31 :0] Alu_Result//结果
);
reg [31:0] Alu_Src1;
reg [31:0] Alu_Src2;
always@(*)
begin
Alu_Src1 = (Alu_SrcA == 0) ? ReadData1 : sa;
Alu_Src2 = (Alu_SrcB == 0) ? ReadData2 : extend;
//位运算中负数以补码形式参加
if(Alu_Op==4'b0001)//无符号加法
Alu_Result<=Alu_Src1+Alu_Src2;
else if(Alu_Op==4'b0010)//无符号减法
Alu_Result<=Alu_Src1-Alu_Src2;
else if(Alu_Op==4'b0011)//有符号比较,小于置位1
Alu_Result<=(((ReadData1 < ReadData2) && (ReadData1[31] == ReadData2[31] )) ||( ( ReadData1[31] ==1 && ReadData2[31] == 0))) ? 1:0;
else if(Alu_Op==4'b0100)//按位与
Alu_Result<=Alu_Src1&Alu_Src2;
else if(Alu_Op==4'b0101)//按位或非
Alu_Result<=~(Alu_Src1|Alu_Src2);
else if(Alu_Op==4'b0110)//按位或
Alu_Result<=(Alu_Src1|Alu_Src2);
else if(Alu_Op==4'b0111)//按位异或
Alu_Result<=(Alu_Src1^Alu_Src2);
else if(Alu_Op==4'b1000)//逻辑左移
Alu_Result<=Alu_Src2<<Alu_Src1;
else if(Alu_Op==4'b1001)//逻辑右移
Alu_Result<=Alu_Src2>>Alu_Src1;
else Alu_Result<=31'b0;
zero=(Alu_Result==0)?1:0;
end
endmodule
DataMemory
module DataMemory(
input clk,
input wenr,//读使能
input wenw,//写使能
input DBDataSrc,//MemtoReg数据保存的选择端,为0来自ALU运算结果的输出,为1来自数据寄存器(Data MEM)的输出
input [31:0] DAddr,//若为LW指令则DAddr=aluResult
input [31:0] DataIn,
output reg[31:0]DataOut,
output reg[31:0] DB,
input [31:0] test_addr,
output reg[31:0] test_data
);
initial begin
DB<=16'b0;
end
reg[31:0]ram[255:0];
integer i;
initial begin
for(i=0;i<=31;i=i+1)
begin
ram[i]=0;
end
end
//写使能,地址不为0,
always@(wenr or DAddr or DBDataSrc)
begin
//读
DataOut[31:0] = wenr ? ram[DAddr] : 32'bz; // z 为高阻态
DB = (DBDataSrc == 0) ? DAddr : DataOut;
end
always@(*)
begin
//测试
test_data[31:0] = ram[test_addr];
end
always@(posedge clk)
begin
//写
if(wenw)
begin
ram[DAddr] = DataIn[31:0];
end
//$display("mwr: %d $12 %d %d %d %d", mWR, ram[12], ram[13], ram[14], ram[15]);
end
endmodule
ControlUnit
module ControlUnit(
input [5:0] opCode,
input zero,
input [5:0] Func,
output reg PCWre,//=1,PC可变
output reg AluSrcA,
output reg AluSrcB,
output reg DBDataSrc,//数据保存的选择端,为0来自ALU运算结果的输出,为1来自数据寄存器(Data MEM)的输出
output reg RegWre,
output reg mRD,//数据存储器的读使能
output reg mWR,//数据存储器的写使能
output reg ExtSel,//立即数扩展
output reg RegDst,//写寄存器组寄存器的地址,为0的时候地址来自rt,为1的时候地址来自rd
output reg [1:0]PCSrc,//控制PC的
output reg [3:0]Alu_Op
);
initial begin
PCWre=1;
mRD=0;
mWR=0;
DBDataSrc=0;
end
always@(*)
begin
PCWre = (opCode == 6'b111111) ? 0 : 1; //halt
mWR = (opCode == 6'b101011) ? 1 : 0; //写存储器使能,sw,寄存器->存储器
mRD = (opCode == 6'b100011) ? 1 : 0; //读使能,lw存储器->寄存器
DBDataSrc = (opCode == 6'b100011) ? 1 : 0;
if(opCode==6'b000000&&Func==6'b100001)//ADDU 1
begin
ExtSel = 0;
RegDst = 1;
RegWre = 1;
AluSrcA = 0;
AluSrcB = 0;
PCSrc = 2'b00;
Alu_Op = 4'b0001;
end
else if(opCode==6'b000000&&Func==6'b100011)//SUBU 2
begin
ExtSel = 0;
RegDst = 1;
RegWre = 1;
AluSrcA = 0;
AluSrcB = 0;
PCSrc = 2'b00;
Alu_Op = 4'b0010;
end
else if(opCode==6'b000000&&Func==6'b101010)//SLT 3
begin
ExtSel = 0;
RegDst = 1;
RegWre = 1;
AluSrcA = 0;
AluSrcB = 0;
PCSrc = 2'b00;
Alu_Op = 4'b0011;
end
else if(opCode==6'b000000&&Func==6'b100100)//AND 4
begin
ExtSel = 0;
RegDst = 1;
RegWre = 1;
AluSrcA = 0;
AluSrcB = 0;
PCSrc = 2'b00;
Alu_Op = 4'b0100;
end
else if(opCode==6'b000000&&Func==6'b100111)//NOR 5
begin
ExtSel = 0;
RegDst = 1;
RegWre = 1;
AluSrcA = 0;
AluSrcB = 0;
PCSrc = 2'b00;
Alu_Op = 4'b0101;
end
else if(opCode==6'b000000&&Func==6'b100101)//OR 6
begin
ExtSel = 0;
RegDst = 1;
RegWre = 1;
AluSrcA = 0;
AluSrcB = 0;
PCSrc = 2'b00;
Alu_Op = 4'b0110;
end
else if(opCode==6'b000000&&Func==6'b100110)//XOR 7
begin
ExtSel = 0;
RegDst = 1;
RegWre = 1;
AluSrcA = 0;
AluSrcB = 0;
PCSrc = 2'b00;
Alu_Op = 4'b0111;
end
else if(opCode==6'b000000&&Func==6'b000000)//SLL 8
begin
ExtSel = 0;
RegDst = 1;
RegWre = 1;
AluSrcA = 1;
AluSrcB = 0;
PCSrc = 2'b00;
Alu_Op = 4'b1000;
end
else if(opCode==6'b000000&&Func==6'b000010)//SRL 9
begin
ExtSel = 0;
RegDst = 1;
RegWre = 1;
AluSrcA = 1;
AluSrcB = 0;
PCSrc = 2'b00;
Alu_Op = 4'b1001;
end
else if(opCode==6'b001001)//ADDIU 10
begin
ExtSel = 1;
RegDst = 0;
RegWre = 1;
AluSrcA = 0;
AluSrcB = 1;
PCSrc = 2'b00;
Alu_Op = 4'b0001;
end
else if(opCode==6'b000100)//BEQ 11
begin
ExtSel = 1;
RegDst = 0;
RegWre = 0;
AluSrcA = 0;
AluSrcB = 0;
PCSrc = zero ? 2'b01 : 2'b00;
Alu_Op = 4'b0010;//减法判断是否相
end
else if(opCode==6'b000101)//BNE 12
begin
ExtSel = 1;
RegDst = 0;
RegWre = 0;
AluSrcA = 0;
AluSrcB = 0;
PCSrc = zero ? 2'b00 : 2'b01;
Alu_Op = 4'b0010;//减法判断是否相
end
else if(opCode==6'b100011)//LW读存储器 13
begin
ExtSel = 1;
RegDst = 0;
RegWre = 1;
AluSrcA = 0;
AluSrcB = 1;
PCSrc = 2'b00;
Alu_Op = 4'b0001;
end
else if(opCode==6'b101011)//SW写存储器 14
begin
ExtSel = 1;
RegDst = 0;
RegWre = 0;
AluSrcA = 0;
AluSrcB = 1;
PCSrc = 2'b00;
Alu_Op = 4'b0001;
end
else if(opCode==6'b000010)//J型直接跳转 15
begin
ExtSel=0;
RegDst=0;
RegWre=0;
AluSrcA=0;
AluSrcB=0;
PCSrc=2'b10;
Alu_Op=0;
end
else
begin
ExtSel=0;
RegDst=0;
RegWre=0;
AluSrcA=0;
AluSrcB=0;
PCSrc=2'b11;
Alu_Op=0;
end
end
endmodule
旧的xdc
#鏃堕挓淇″彿杩炴帴
set_property PACKAGE_PIN AC19 [get_ports clk]
#鑴夊啿寮?鍏筹紝鐢ㄤ簬杈撳叆浣滀负澶嶄綅淇″彿锛屼綆鐢靛钩鏈夋晥
set_property PACKAGE_PIN Y3 [get_ports resetn]
#led鐏繛鎺ワ紝鐢ㄤ簬杈撳嚭
set_property IOSTANDARD LVCMOS33 [get_ports clk]
set_property IOSTANDARD LVCMOS33 [get_ports resetn]
#瑙︽懜灞忓紩鑴氳繛鎺?
set_property PACKAGE_PIN J25 [get_ports lcd_rst]
set_property PACKAGE_PIN H18 [get_ports lcd_cs]
set_property PACKAGE_PIN K16 [get_ports lcd_rs]
set_property PACKAGE_PIN L8 [get_ports lcd_wr]
set_property PACKAGE_PIN K8 [get_ports lcd_rd]
set_property PACKAGE_PIN J15 [get_ports lcd_bl_ctr]
set_property PACKAGE_PIN H9 [get_ports {lcd_data_io[0]}]
set_property PACKAGE_PIN K17 [get_ports {lcd_data_io[1]}]
set_property PACKAGE_PIN J20 [get_ports {lcd_data_io[2]}]
set_property PACKAGE_PIN M17 [get_ports {lcd_data_io[3]}]
set_property PACKAGE_PIN L17 [get_ports {lcd_data_io[4]}]
set_property PACKAGE_PIN L18 [get_ports {lcd_data_io[5]}]
set_property PACKAGE_PIN L15 [get_ports {lcd_data_io[6]}]
set_property PACKAGE_PIN M15 [get_ports {lcd_data_io[7]}]
set_property PACKAGE_PIN M16 [get_ports {lcd_data_io[8]}]
set_property PACKAGE_PIN L14 [get_ports {lcd_data_io[9]}]
set_property PACKAGE_PIN M14 [get_ports {lcd_data_io[10]}]
set_property PACKAGE_PIN F22 [get_ports {lcd_data_io[11]}]
set_property PACKAGE_PIN G22 [get_ports {lcd_data_io[12]}]
set_property PACKAGE_PIN G21 [get_ports {lcd_data_io[13]}]
set_property PACKAGE_PIN H24 [get_ports {lcd_data_io[14]}]
set_property PACKAGE_PIN J16 [get_ports {lcd_data_io[15]}]
set_property PACKAGE_PIN L19 [get_ports ct_int]
set_property PACKAGE_PIN J24 [get_ports ct_sda]
set_property PACKAGE_PIN H21 [get_ports ct_scl]
set_property PACKAGE_PIN G24 [get_ports ct_rstn]
set_property IOSTANDARD LVCMOS33 [get_ports lcd_rst]
set_property IOSTANDARD LVCMOS33 [get_ports lcd_cs]
set_property IOSTANDARD LVCMOS33 [get_ports lcd_rs]
set_property IOSTANDARD LVCMOS33 [get_ports lcd_wr]
set_property IOSTANDARD LVCMOS33 [get_ports lcd_rd]
set_property IOSTANDARD LVCMOS33 [get_ports lcd_bl_ctr]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[8]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[9]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[10]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[11]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[12]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[13]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[14]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[15]}]
set_property IOSTANDARD LVCMOS33 [get_ports ct_int]
set_property IOSTANDARD LVCMOS33 [get_ports ct_sda]
set_property IOSTANDARD LVCMOS33 [get_ports ct_scl]
set_property IOSTANDARD LVCMOS33 [get_ports ct_rstn]
功能仿真
tb
`timescale 1ns / 1ps
module tb;
//inputs
reg clk;
reg Reset;
reg [31:0]test_addr;
wire [31:0]test_data;
reg [4:0]test_addr1;
wire [31:0]test_data1;
SingleCycleCPU ins(
.clk(clk),
.Reset(Reset),
.test_addr(test_addr),
.test_data(test_data),
.test_addr1(test_addr1),
.test_data1(test_data1)
);
initial begin
clk=1;
Reset=0;
test_addr=1;
test_addr1=31;
#10
Reset=1;
#180
test_addr=1;
#2
test_addr=2;
#2
test_addr=3;
#2
test_addr=4;
#2
test_addr=5;
#2
test_addr=6;
#2
test_addr=7;
#2
test_addr=8;
#576
test_addr=1;
#2
test_addr=2;
#2
test_addr=3;
#2
test_addr=4;
#2
test_addr=5;
#2
test_addr=6;
#2
test_addr=7;
#2
test_addr=8;
#496
test_addr=1;
#2
test_addr=2;
#2
test_addr=3;
#2
test_addr=4;
#2
test_addr=5;
#2
test_addr=6;
#2
test_addr=7;
#2
test_addr=8;
#416
test_addr=1;
#2
test_addr=2;
#2
test_addr=3;
#2
test_addr=4;
#2
test_addr=5;
#2
test_addr=6;
#2
test_addr=7;
#2
test_addr=8;
#336
test_addr=1;
#2
test_addr=2;
#2
test_addr=3;
#2
test_addr=4;
#2
test_addr=5;
#2
test_addr=6;
#2
test_addr=7;
#2
test_addr=8;
#256
test_addr=1;
#2
test_addr=2;
#2
test_addr=3;
#2
test_addr=4;
#2
test_addr=5;
#2
test_addr=6;
#2
test_addr=7;
#2
test_addr=8;
#176
test_addr=1;
#2
test_addr=2;
#2
test_addr=3;
#2
test_addr=4;
#2
test_addr=5;
#2
test_addr=6;
#2
test_addr=7;
#2
test_addr=8;
#96
test_addr=1;
#2
test_addr=2;
#2
test_addr=3;
#2
test_addr=4;
#2
test_addr=5;
#2
test_addr=6;
#2
test_addr=7;
#2
test_addr=8;
test_addr1=31;
#8000
test_addr=1;
#2
test_addr=2;
#2
test_addr=3;
#2
test_addr=4;
#2
test_addr=5;
#2
test_addr=6;
#2
test_addr=7;
#2
test_addr=8;
end
always #5 clk = ~clk;
endmodule
上板验证
思考
这个代码不是一次就跑成了的,在旧板子和新板子上,第一次都没跑成功,去请教了上一届的一位学长,学长说是数组可能超限,把一个大小为5的数组改成6就过了。按照学长说的把5改6果然过了,但是我还是不明白为什么超限,我觉得我的逻辑结构是没有问题的,后来又把6改成5(和一开始的代码一样了),结果也过了。我觉得我的代码是没问题的,这个板子就很迷惑,不稳定感觉,毕竟不是学电子的,还是不知道到底是哪里的问题。