如题,自己做的,还不完善,没RAM,只有通用寄存器,指令只有取指,IO指令,跳转指令和空指令(因为有这几个指令就可以FPGA验证in,out看结果了),自然没法用,可以给学习Verilog的同学和学习CPU结构的同学用~
`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Engineer: LJT // Create Date: 08:53:12 11/21/2010 // Module Name: top_modu ////////////////////////////////////////////////////////////////////////////////// module top_modu(clk,rst,P1_IN,P1_OUT); //IO Part input clk; input rst; input [7:0] P1_IN; output [7:0] P1_OUT; //BUS wire [7:0] DB_IN; //data bus wire [7:0] DB_OUT; wire [7:0] ABUS; //address bus wire [7:0] CBUS; // ctrl bus //各模块间互连线 wire [7:0]irdb_out; wire [7:0]iodb_in; wire [7:0]iodb_out; //Ctrl_Unit ctrl_unit ctrl_unit ( .clk(clk), .rst(rst), .DB_IN(DB_IN), .DB_OUT(DB_OUT), .ABUS(ABUS), .CBUS(CBUS) ); //instruction rom instru_rom instru_rom ( .clk(clk), .addr(ABUS), .db_out(irdb_out) ); //bus interface module bus_if_modu bus_if_modu ( .CBUS(CBUS), .DB_IN(DB_IN), .DB_OUT(DB_OUT), .irdb_out(irdb_out), .iodb_in(iodb_in), .iodb_out(iodb_out) ); //io interface io_modu io_modu ( .clk(clk), .db_in(iodb_in), .db_out(iodb_out), .P1_IN(P1_IN), .P1_OUT(P1_OUT) ); Endmodule `timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: SDU // Engineer: Lijiangtao // Create Date: 22:28:42 11/16/2010 // Module Name: Ctrl_Unit // Revision 0.01 ////////////////////////////////////////////////////////////////////////////////// module ctrl_unit(clk,rst,DB_IN,DB_OUT,ABUS,CBUS); //IO part input clk; input rst; input [7:0] DB_IN; output reg [7:0] DB_OUT; output reg [7:0] ABUS;//address bus output [7:0]CBUS; reg [3:0] CBUS_IN;// ctrl bus in&out reg [3:0] CBUS_OUT; assign CBUS[3:0]=CBUS_IN[3:0]; assign CBUS[7:4]=CBUS_OUT[3:0]; //important register reg [7:0] PC; reg [7:0] IR; reg [7:0] MSR; //general reg reg [7:0] A; reg [7:0] B; reg [7:0] C; reg [7:0] D; //Instruction Cycle Count reg [2:0] In_Cy; //A Temp register reg [7:0] RTMP; //instructions parameter[7:0] NOP = 8'b01100000; parameter[7:0] JMP = 8'b01100001; parameter[7:0] IN = 8'b01100010; parameter[7:0] OUT = 8'b01100011; parameter[7:0] MOV1 = 8'b10000001; parameter[7:0] MOV2 = 8'b10000010; //4 bits, @bus address---挂在总线上的外设ID parameter[3:0] CUID = 4'h1; //Contrl Uint parameter[3:0] ROMID = 4'h6; //instrution@ ---Harward Architecture parameter[3:0] RAMID = 4'he; //data parameter[3:0] INID = 4'h4; //IO parameter[3:0] OUTID = 4'h5; ///////////////////////////////////////////////////////////////////////////// //PC description //In_Cy==1 取指; 0时 PC+1 always@(posedge clk) begin if(rst==1) PC<=0; else if(IR==JMP&&In_Cy==1) //JMP instruction PC<=DB_IN; else if(MSR[7]==1||In_Cy==0) //取指 or 取操作数 --at next cycle PC<=PC+1; else PC<=PC; end //In_Cy description: instruction cycle count always@(posedge clk) begin if(rst==1) In_Cy<=3; //In_Cy==0时,PC++,In_Cy==1时取指 else if(In_Cy==0) In_Cy<=IR[7:5]; //IR[7:5]设置为该指令的(执行周期数-1),不大于32条指令(实际上可以更多)的情况下可以减小译码所占用面积 else In_Cy<=In_Cy-1; end //IR description : instruction register always@(posedge clk) begin if(In_Cy==1) //取指 begin IR<=DB_IN; end else IR<=IR; end /////////////////////////////////////////////////////////////////////////////////// //Here Describ: reg ABCD, RTMP, ABUS, CBUS_IN, CBUS_OUT, DB_OUT , MSR[7] //the main frame is here //the most important part of this deaign //In_Cy-- 4:... 3:PC->abus 2:CBUS 1:取指 0:PC+1 /////////////////////////////////////////////////////////////////////////////////// always@(posedge clk) begin if(rst||In_Cy==2) //下周期取指 begin CBUS_IN<=CUID; CBUS_OUT<=ROMID; MSR[7]<=0; ABUS<=PC; end else begin //指令译码 case (IR) //在不同的机器周期(IN_CY)内执行不同的操作 //3时改变地址总线,2时选通指令存储器,1时取指,0时PC加1; //2,1时无法执行其他操作,3,0时可以同时执行其他操作,但要注意地址总线和没变的PC值 NOP: case (In_Cy) //上次1时取指NOP,上次是0时incy被赋值1,然后直接取指下一条,因此在0时准备取指 4T 3'd0: begin CBUS_IN<=CUID; CBUS_OUT<=ROMID; end 3'd3: begin ABUS<=PC; end endcase JMP: case (In_Cy) //上次1时取指JMP,上次是0时incy被赋值1,然后直接取指下一条 4T 3'd0: //准备取操作数 begin CBUS_OUT<=ROMID; CBUS_IN<=CUID; end 3'd3: //操作数给PC在PC的描述里,取操作数--注意指令存储器的设计 begin ABUS<=PC; end endcase IN: case (In_Cy) //IN=>寄存器A 4T 3'd0: begin CBUS_OUT<=INID; CBUS_IN<=CUID; end 3'd3: begin A<=DB_OUT; ABUS<=PC; end endcase OUT: case (In_Cy) //取寄存器A,给OUT 4T 3'd0: begin CBUS_OUT<=CUID; CBUS_IN<=OUTID; DB_OUT<=A; end 3'd3: //IO要在这个时钟周期锁存 begin ABUS<=PC; end endcase MOV1: case (In_Cy) //未完成 3'd0: //准备取操作数 begin CBUS_OUT<=ROMID; CBUS_IN<=CUID; ABUS<=PC; MSR[7]<=1; end 3'd4: //取操作数 begin RTMP<=DB_IN; MSR[7]<=0; CBUS_OUT<=INID; CBUS_IN<=RAMID; A<=DB_IN; B<=DB_IN; end 3'd3: begin CBUS_OUT<=RAMID; CBUS_IN<=CUID; ABUS<=PC; MSR[7]<=1; C<=DB_IN; D<=DB_IN; end endcase endcase //指令译码部分结束 end end endmodule `timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Engineer: LJT ////////////////////////////////////////////////////////////////////////////////// module instru_rom(clk,addr, db_out); input clk; input [7:0]addr; output [7:0]db_out; wire [10:0] addr11; IN_ROM IN_ROM ( .addr_11(addr11), .data_8(db_out), .clk(clk) ); assign addr11[10:8]=0; assign addr11[7:0]=addr[7:0]; endmodule module IN_ROM(addr_11, data_8, clk); input clk; input [10:0] addr_11; output [7:0] data_8; RAMB16_S9 #( .INIT(9'h000), // Value of output RAM registers at startup .SRVAL(9'h000), // Output value upon SSR assertion .WRITE_MODE("WRITE_FIRST"), // WRITE_FIRST, READ_FIRST or NO_CHANGE // The following INIT_xx declarations specify the initial contents of the RAM // Address 0 to 511 .INIT_00(256'h62_63_62_63_61_00_61_00_61_00_00_00_00_00_0(后面全为0) ) RAMB16_S9_inst ( .DO(data_8), // 8-bit Data Output-------------------- .DOP(DOP), // 1-bit parity Output --to a reg .ADDR(addr_11), // 11-bit Address Input -----------------change to 8bit,others 0. .CLK(clk), // Clock .DI(DI), // 8-bit Data Input --0 .DIP(DIP), // 1-bit parity Input --0 .EN(EN), // RAM Enable Input --1 .SSR(SSR), // Synchronous Set/Reset Input --0 .WE(WE) // Write Enable Input --0 ); //End of RAMB16_S9_inst instantiation //assign addr_8=ADDR[7:0]; //assign ADDR[10:8]=0; assign DI=0; assign DIP=0; assign EN=1; assign SSR=0; assign WE=0; endmodule `timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // Create Date: 16:14:41 11/21/2010 // Module: Bus_Interface_Module ////////////////////////////////////////////////////////////////////////////////// module bus_if_modu(CBUS, DB_IN,DB_OUT, irdb_out, //instru rom iodb_in,iodb_out //io ); input [7:0] CBUS; input [7:0] DB_OUT; output reg [7:0] DB_IN; input [7:0] irdb_out; input [7:0] iodb_out; output reg [7:0] iodb_in; //挂在总线上的外设ID parameter[3:0] CUID = 4'h1; //Contrl Uint parameter[3:0] ROMID = 4'h6; //instrution@ ---Harward Architecture parameter[3:0] RAMID = 4'he; //data parameter[3:0] INID = 4'h4; //IO parameter[3:0] OUTID = 4'h5; always @ (CBUS[7:4]) begin case (CBUS[7:4]) ROMID: DB_IN <= irdb_out; INID: DB_IN <= iodb_out; RAMID: DB_IN <= irdb_out; endcase end always @ (CBUS[3:0]) begin case (CBUS[3:0]) OUTID: iodb_in <= DB_OUT; RAMID: iodb_in <= DB_OUT; endcase end endmodule `timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Design Name: // Module Name: io_modu ////////////////////////////////////////////////////////////////////////////////// module io_modu(clk, db_in, db_out, P1_IN, P1_OUT ); input clk; input [7:0] P1_IN; input [7:0] db_in; output reg [7:0] P1_OUT; output reg [7:0] db_out; always@(posedge clk) begin P1_OUT[7:0]<=db_in[7:0]; db_out[7:0]<=P1_IN[7:0]; end endmodule |
|