processing_unit.v

来自「这是我同学在上海交大实习的时候做的一个单片机的verilog代码实现」· Verilog 代码 · 共 212 行

V
212
字号
module Processing_Unit (instruction, Zflag, Carrier_flag, address, Bus_1, mem_word, Load_R0, Load_R1, Load_R2, 
  Load_R3, Load_PC, Inc_PC, Sel_Bus_1_Mux, Load_IR, Load_Add_R, Load_Reg_Y, Load_Reg_Z, Load_Carrier,
  Sel_Bus_2_Mux, clk, rst);

  parameter word_size = 16;
  parameter address_size = 8;
  parameter op_size = 4;
  parameter Sel1_size = 3;
  parameter Sel2_size = 2;

  output [word_size-1: 0] 	instruction, Bus_1;
  output [address_size-1 : 0] address;
  output Zflag, Carrier_flag;

  input [word_size-1: 0]  	mem_word;
  input 			Load_R0, Load_R1, Load_R2, Load_R3, Load_PC, Inc_PC;
  input [Sel1_size-1: 0] 	Sel_Bus_1_Mux;
  input [Sel2_size-1: 0] 	Sel_Bus_2_Mux;
  input 			Load_IR, Load_Add_R, Load_Reg_Y, Load_Reg_Z, Load_Carrier;
  input 			clk, rst;

  wire			Load_R0, Load_R1, Load_R2, Load_R3;
  wire [word_size-1: 0] 	Bus_2;
  wire [word_size-1: 0] 	R0_out, R1_out, R2_out, R3_out;
  wire [word_size-1: 0] 	PC_count, Y_value, alu_out;
  wire 			alu_zero_flag, carrier;
  wire [op_size-1 : 0] 	opcode = instruction [word_size-1: word_size-op_size];

  Register_Unit 		R0 	(R0_out, Bus_2, Load_R0, clk, rst);
  Register_Unit 		R1 	(R1_out, Bus_2, Load_R1, clk, rst);
  Register_Unit 		R2 	(R2_out, Bus_2, Load_R2, clk, rst);
  Register_Unit 		R3 	(R3_out, Bus_2, Load_R3, clk, rst);
  Register_Unit 		Reg_Y 	(Y_value, Bus_2, Load_Reg_Y, clk, rst);
  D_flop 			Reg_Z 	(Zflag, alu_zero_flag, Load_Reg_Z, clk, rst);
  D_flop    Reg_C   (Carrier_flag, carrier, Load_Carrier, clk, rst);
  Address_Register 	Add_R	(address, Bus_2, Load_Add_R, clk, rst);//
  Instruction_Register	IR	(instruction, Bus_2, Load_IR, clk, rst);
  Program_Counter 	PC	(PC_count, Bus_2, Load_PC, Inc_PC, clk, rst);
  Multiplexer_6ch 		Mux_1 	(Bus_1, R0_out, R1_out, R2_out, R3_out, PC_count, instruction, Sel_Bus_1_Mux);
  Multiplexer_3ch 		Mux_2	(Bus_2, alu_out, Bus_1, mem_word, Sel_Bus_2_Mux);
  Alu_RISC 		ALU	(alu_zero_flag, carrier, alu_out, Y_value, Bus_1, opcode);
endmodule 

module Register_Unit (data_out, data_in, load, clk, rst);
  parameter 		word_size = 16;
  output [word_size-1: 0] 	data_out;
  input 	[word_size-1: 0] 	data_in;
  input 			load;
  input 			clk, rst;
  reg 	[word_size-1: 0]	data_out;

  always @ (posedge clk or negedge rst)
    if (rst == 0) 
       data_out <= 0; 
    else if (load) 
       data_out <= data_in;//这是什么意思?
endmodule

module D_flop (data_out, data_in, load, clk, rst);
  output 		data_out;
  input 		data_in;
  input 		load;
  input 		clk, rst;
  reg 		data_out;

  always @ (posedge clk or negedge rst)
    if (rst == 0) 
       data_out <= 0; 
    else if (load == 1)
       data_out <= data_in;
endmodule

 module Address_Register (data_out, data_in, load, clk, rst);
  parameter word_size = 16;
  parameter address_size = 8;
  output [address_size-1: 0] 	data_out;
  input 	[word_size-1: 0] 	data_in;
  input 			load, clk, rst;
  reg 	[address_size-1: 0]	data_out;
  always @ (posedge clk or negedge rst)
    if (rst == 0) 
       data_out <= 0; 
    else if (load) 
    data_out <= data_in[address_size-1:0];
endmodule

module Instruction_Register (data_out, data_in, load, clk, rst);
  parameter word_size = 16;
  output [word_size-1: 0] 	data_out;
  input 	[word_size-1: 0] 	data_in;
  input 			load;
  input 			clk, rst;
  reg 	[word_size-1: 0]	data_out;
  always @ (posedge clk or negedge rst)
    if (rst == 0) 
       data_out <= 0; 
    else if (load) 
       data_out <= data_in; 
endmodule

module Program_Counter (count, data_in, Load_PC, Inc_PC, clk, rst);
  parameter word_size = 16;
  parameter address_size = 8;
  output [word_size-1: 0] 	count;
  input 	[word_size-1: 0] 	data_in;
  input 			Load_PC, Inc_PC;
  input 			clk, rst;
  reg 	[word_size-1: 0]	count;
  always @ (posedge clk or negedge rst)
    if (rst == 0) count <= 20; 
    else if (Load_PC)  
    begin
        count[address_size-1:0] <= data_in[address_size-1:0];
        count[word_size-1:address_size] <= 0; 
    end  
    else if  (Inc_PC) //程序计数器
    begin
        count[address_size-1:0] <= count[address_size-1:0] +1;
        count[word_size-1:address_size] <=0;
    end
endmodule

module Multiplexer_6ch (mux_out, data_a, data_b, data_c, data_d, data_e, data_f, sel);
  parameter word_size = 16;
  output [word_size-1: 0] 	mux_out;
  input 	[word_size-1: 0] 	data_a, data_b, data_c, data_d, data_e, data_f;
  input 	[2: 0] sel;
 
  assign  mux_out = (sel == 0) 	? data_a: (sel == 1) 
                                ? data_b : (sel == 2) 
                                ? data_c: (sel == 3) 
                                ? data_d : (sel == 4) 
                                ? data_e : (sel == 5)
                                ? data_f : 'bx;
endmodule

module Multiplexer_3ch (mux_out, data_a, data_b, data_c, sel);
  parameter 	word_size = 16;
  output 		[word_size-1: 0]	 mux_out;
  input 		[word_size-1: 0] 	data_a, data_b, data_c;
  input 		[1: 0] sel;

  assign  mux_out = (sel == 0) ? data_a: 
                    (sel == 1) ? data_b : 
                    (sel == 2) ? data_c: 'bx;
endmodule
 


/*ALU Instruction		Action
ADD			Adds the datapaths to form data_1 + data_2.
SUB			Subtracts the datapaths to form data_1 - data_2.
AND			Takes the bitwise-and of the datapaths, data_1 & data_2.
NOT			Takes the bitwise Boolean complement of data_1.
*/
// Note: the carries are ignored in this model.
 
module Alu_RISC (alu_zero_flag, carrier, alu_out, data_1, data_2, sel);
  parameter word_size = 16;
  parameter op_size = 4;
  // Opcodes
  parameter NOP 	= 4'b0000;//定义各种操作符
  parameter ADD 	= 4'b0001;
  parameter SUB 	= 4'b0010;
  //parameter AND 	= 4'b0011;
  parameter DCC 	= 4'b0100;
  parameter RD  		= 4'b0101;
  parameter WR		= 4'b0110;
  parameter ID_WR = 4'b0011;
  parameter BR		= 4'b0111;
  parameter BRZ 		= 4'b1000;

  parameter ADDC = 4'b1001;
  parameter ID_RD = 4'b1010;
  parameter shift = 4'b1011;
  parameter ACC = 4'b1100;
  parameter BRC = 4'b1101;
  parameter compare = 4'b1110;
  parameter LD = 4'b1111;

  output 			alu_zero_flag;
  output    carrier;
  output [word_size-1: 0] 	alu_out;
  input 	[word_size-1: 0] 	data_1, data_2;
  input 	[op_size-1: 0] 	sel;
  reg 	[word_size-1: 0]	alu_out;
  reg carrier;

  assign  alu_zero_flag = ~|alu_out;
  always @ (sel or data_1 or data_2)  //定义各种操作的动作
     case  (sel)
      NOP:	alu_out = 0;
      ADD:	alu_out = data_1 + data_2;  // Reg_Y + Bus_1
      SUB:	alu_out = data_2 - data_1;
      //AND:	alu_out = data_1 & data_2;
      //NOT:	alu_out = ~ data_2;	 // Gets data from Bus_1
      ADDC: {carrier,alu_out} = data_1 + data_2;
      ACC: alu_out = data_2 + 1;
      DCC: alu_out = data_2 - 1;
      shift: alu_out = {data_1[3:0], data_2[15:4]};
      LD   : alu_out = data_1;
      compare: begin
          if(data_1 < data_2)
                carrier = 1;
           else
                carrier = 0;
      end
      BRZ: alu_out = data_2;
      default: 	alu_out = 0;
    endcase 
endmodule

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?