Question

In: Electrical Engineering

Design and write a verilog code and testbench for a 16-bit RISC MIPS Processor on vivado...

Design and write a verilog code and testbench for a 16-bit RISC MIPS Processor on vivado and show waveform.

Solutions

Expert Solution

Verilog code for Data memory:

module data_memory  
 (  
      input                         clk,  
      // address input, shared by read and write port  
      input     [15:0]               mem_access_addr,  
      // write port  
      input     [15:0]               mem_write_data,  
      input                         mem_write_en,  
      input mem_read,  
      // read port  
      output     [15:0]               mem_read_data  
 );  
      integer i;  
      reg [15:0] ram [255:0];  
      wire [7 : 0] ram_addr = mem_access_addr[8 : 1];  
      initial begin  
           for(i=0;i<256;i=i+1)  
                ram[i] <= 16'd0;  
      end  
      always @(posedge clk) begin  
           if (mem_write_en)  
                ram[ram_addr] <= mem_write_data;  
      end  
      assign mem_read_data = (mem_read==1'b1) ? ram[ram_addr]: 16'd0;   
 endmodule   

Verilog code for ALU control unit:

module ALUControl( ALU_Control, ALUOp, Function);  
 output reg[2:0] ALU_Control;  
 input [1:0] ALUOp;  
 input [3:0] Function;  
 wire [5:0] ALUControlIn;  
 assign ALUControlIn = {ALUOp,Function};  
 always @(ALUControlIn)  
 casex (ALUControlIn)  
  6'b11xxxx: ALU_Control=3'b000;  
  6'b10xxxx: ALU_Control=3'b100;  
  6'b01xxxx: ALU_Control=3'b001;  
  6'b000000: ALU_Control=3'b000;  
  6'b000001: ALU_Control=3'b001;  
  6'b000010: ALU_Control=3'b010;  
  6'b000011: ALU_Control=3'b011;  
  6'b000100: ALU_Control=3'b100;  
  default: ALU_Control=3'b000;  
  endcase  
 endmodule  
// Verilog code for JR control unit
module JR_Control( input[1:0] alu_op, 
       input [3:0] funct,
       output JRControl
    );
assign JRControl = ({alu_op,funct}==6'b001000) ? 1'b1 : 1'b0;
endmodule

Verilog code for control unit:

module control( input[2:0] opcode,  
                           input reset,  
                           output reg[1:0] reg_dst,mem_to_reg,alu_op,  
                           output reg jump,branch,mem_read,mem_write,alu_src,reg_write,sign_or_zero                      
   );  
 always @(*)  
 begin  
      if(reset == 1'b1) begin  
                reg_dst = 2'b00;  
                mem_to_reg = 2'b00;  
                alu_op = 2'b00;  
                jump = 1'b0;  
                branch = 1'b0;  
                mem_read = 1'b0;  
                mem_write = 1'b0;  
                alu_src = 1'b0;  
                reg_write = 1'b0;  
                sign_or_zero = 1'b1;  
      end  
      else begin  
      case(opcode)   
      3'b000: begin // add  
                reg_dst = 2'b01;  
                mem_to_reg = 2'b00;  
                alu_op = 2'b00;  
                jump = 1'b0;  
                branch = 1'b0;  
                mem_read = 1'b0;  
                mem_write = 1'b0;  
                alu_src = 1'b0;  
                reg_write = 1'b1;  
                sign_or_zero = 1'b1;  
                end  
      3'b001: begin // sli  
                reg_dst = 2'b00;  
                mem_to_reg = 2'b00;  
                alu_op = 2'b10;  
                jump = 1'b0;  
                branch = 1'b0;  
                mem_read = 1'b0;  
                mem_write = 1'b0;  
                alu_src = 1'b1;  
                reg_write = 1'b1;  
                sign_or_zero = 1'b0;  
                end  
      3'b010: begin // j  
                reg_dst = 2'b00;  
                mem_to_reg = 2'b00;  
                alu_op = 2'b00;  
                jump = 1'b1;  
                branch = 1'b0;  
                mem_read = 1'b0;  
                mem_write = 1'b0;  
                alu_src = 1'b0;  
                reg_write = 1'b0;  
                sign_or_zero = 1'b1;  
                end  
      3'b011: begin // jal  
                reg_dst = 2'b10;  
                mem_to_reg = 2'b10;  
                alu_op = 2'b00;  
                jump = 1'b1;  
                branch = 1'b0;  
                mem_read = 1'b0;  
                mem_write = 1'b0;  
                alu_src = 1'b0;  
                reg_write = 1'b1;  
                sign_or_zero = 1'b1;  
                end  
      3'b100: begin // lw  
                reg_dst = 2'b00;  
                mem_to_reg = 2'b01;  
                alu_op = 2'b11;  
                jump = 1'b0;  
                branch = 1'b0;  
                mem_read = 1'b1;  
                mem_write = 1'b0;  
                alu_src = 1'b1;  
                reg_write = 1'b1;  
                sign_or_zero = 1'b1;  
                end  
      3'b101: begin // sw  
                reg_dst = 2'b00;  
                mem_to_reg = 2'b00;  
                alu_op = 2'b11;  
                jump = 1'b0;  
                branch = 1'b0;  
                mem_read = 1'b0;  
                mem_write = 1'b1;  
                alu_src = 1'b1;  
                reg_write = 1'b0;  
                sign_or_zero = 1'b1;  
                end  
      3'b110: begin // beq  
                reg_dst = 2'b00;  
                mem_to_reg = 2'b00;  
                alu_op = 2'b01;  
                jump = 1'b0;  
                branch = 1'b1;  
                mem_read = 1'b0;  
                mem_write = 1'b0;  
                alu_src = 1'b0;  
                reg_write = 1'b0;  
                sign_or_zero = 1'b1;  
                end  
      3'b111: begin // addi  
                reg_dst = 2'b00;  
                mem_to_reg = 2'b00;  
                alu_op = 2'b11;  
                jump = 1'b0;  
                branch = 1'b0;  
                mem_read = 1'b0;  
                mem_write = 1'b0;  
                alu_src = 1'b1;  
                reg_write = 1'b1;  
                sign_or_zero = 1'b1;  
                end  
      default: begin  
                reg_dst = 2'b01;  
                mem_to_reg = 2'b00;  
                alu_op = 2'b00;  
                jump = 1'b0;  
                branch = 1'b0;  
                mem_read = 1'b0;  
                mem_write = 1'b0;  
                alu_src = 1'b0;  
                reg_write = 1'b1;  
                sign_or_zero = 1'b1;  
                end  
      endcase  
      end  
 end  
 endmodule  

Verilog code for Single cycle MIPS processor:

module mips_16( input clk,reset,  
                           output[15:0] pc_out, alu_result
                           //,reg3,reg4  
   );  
 reg[15:0] pc_current;  
 wire signed[15:0] pc_next,pc2;  
 wire [15:0] instr;  
 wire[1:0] reg_dst,mem_to_reg,alu_op;  
 wire jump,branch,mem_read,mem_write,alu_src,reg_write     ;  
 wire     [2:0]     reg_write_dest;  
 wire     [15:0] reg_write_data;  
 wire     [2:0]     reg_read_addr_1;  
 wire     [15:0] reg_read_data_1;  
 wire     [2:0]     reg_read_addr_2;  
 wire     [15:0] reg_read_data_2;  
 wire [15:0] sign_ext_im,read_data2,zero_ext_im,imm_ext;  
 wire JRControl;  
 wire [2:0] ALU_Control;  
 wire [15:0] ALU_out;  
 wire zero_flag;  
 wire signed[15:0] im_shift_1, PC_j, PC_beq, PC_4beq,PC_4beqj,PC_jr;  
 wire beq_control;  
 wire [14:0] jump_shift_1;  
 wire [15:0]mem_read_data;  
 wire [15:0] no_sign_ext;  
 wire sign_or_zero;  
 // PC   
 always @(posedge clk or posedge reset)  
 begin   
      if(reset)   
           pc_current <= 16'd0;  
      else  
           pc_current <= pc_next;  
 end  
 // PC + 2   
 assign pc2 = pc_current + 16'd2;  
 // instruction memory  
 instr_mem instrucion_memory(.pc(pc_current),.instruction(instr));  
 // jump shift left 1  
 assign jump_shift_1 = {instr[13:0],1'b0};  
 // control unit  
 control control_unit(.reset(reset),.opcode(instr[15:13]),.reg_dst(reg_dst)  
                ,.mem_to_reg(mem_to_reg),.alu_op(alu_op),.jump(jump),.branch(branch),.mem_read(mem_read),  
                .mem_write(mem_write),.alu_src(alu_src),.reg_write(reg_write),.sign_or_zero(sign_or_zero));  
 // multiplexer regdest  
 assign reg_write_dest = (reg_dst==2'b10) ? 3'b111: ((reg_dst==2'b01) ? instr[6:4] :instr[9:7]);  
 // register file  
 assign reg_read_addr_1 = instr[12:10];  
 assign reg_read_addr_2 = instr[9:7];  
 register_file reg_file(.clk(clk),.rst(reset),.reg_write_en(reg_write),  
 .reg_write_dest(reg_write_dest),  
 .reg_write_data(reg_write_data),  
 .reg_read_addr_1(reg_read_addr_1),  
 .reg_read_data_1(reg_read_data_1),  
 .reg_read_addr_2(reg_read_addr_2),  
 .reg_read_data_2(reg_read_data_2)); 
 //.reg3(reg3),  
 //.reg4(reg4));  
 // sign extend  
 assign sign_ext_im = {{9{instr[6]}},instr[6:0]};  
 assign zero_ext_im = {{9{1'b0}},instr[6:0]};  
 assign imm_ext = (sign_or_zero==1'b1) ? sign_ext_im : zero_ext_im;  
 // JR control  
 JR_Control JRControl_unit(.alu_op(alu_op),.funct(instr[3:0]),.JRControl(JRControl));       
 // ALU control unit  
 ALUControl ALU_Control_unit(.ALUOp(alu_op),.Function(instr[3:0]),.ALU_Control(ALU_Control));  
 // multiplexer alu_src  
 assign read_data2 = (alu_src==1'b1) ? imm_ext : reg_read_data_2;  
 // ALU   
 alu alu_unit(.a(reg_read_data_1),.b(read_data2),.alu_control(ALU_Control),.result(ALU_out),.zero(zero_flag));  
 // immediate shift 1  
 assign im_shift_1 = {imm_ext[14:0],1'b0};  
 //  
 assign no_sign_ext = ~(im_shift_1) + 1'b1;  
 // PC beq add  
 assign PC_beq = (im_shift_1[15] == 1'b1) ? (pc2 - no_sign_ext): (pc2 +im_shift_1);  
 // beq control  
 assign beq_control = branch & zero_flag;  
 // PC_beq  
 assign PC_4beq = (beq_control==1'b1) ? PC_beq : pc2;  
 // PC_j  
 assign PC_j = {pc2[15],jump_shift_1};  
 // PC_4beqj  
 assign PC_4beqj = (jump == 1'b1) ? PC_j : PC_4beq;  
 // PC_jr  
 assign PC_jr = reg_read_data_1;  
 // PC_next  
 assign pc_next = (JRControl==1'b1) ? PC_jr : PC_4beqj;  
 // data memory  
 data_memory datamem(.clk(clk),.mem_access_addr(ALU_out),  
 .mem_write_data(reg_read_data_2),.mem_write_en(mem_write),.mem_read(mem_read),  
 .mem_read_data(mem_read_data));  
 // write back  
 assign reg_write_data = (mem_to_reg == 2'b10) ? pc2:((mem_to_reg == 2'b01)? mem_read_data: ALU_out);  
 // output  
 assign pc_out = pc_current;  
 assign alu_result = ALU_out;  
 endmodule  

Verilog testbench code for the single-cycle MIPS processor:

module tb_mips16;  
      // Inputs  
      reg clk;  
      reg reset;  
      // Outputs  
      wire [15:0] pc_out;  
      wire [15:0] alu_result;//,reg3,reg4;  
      // Instantiate the Unit Under Test (UUT)  
      mips_16 uut (  
           .clk(clk),   
           .reset(reset),   
           .pc_out(pc_out),   
           .alu_result(alu_result)  
           //.reg3(reg3),  
          // .reg4(reg4)  
      );  
      initial begin  
           clk = 0;  
           forever #10 clk = ~clk;  
      end  
      initial begin  
           // Initialize Inputs  
           //$monitor ("register 3=%d, register 4=%d", reg3,reg4);  
           reset = 1;  
           // Wait 100 ns for global reset to finish  
           #100;  
     reset = 0;  
           // Add stimulus here  
      end  
 endmodule  

Related Solutions

a) Design a16-bit MIPS Processor in a simplest form in Verilog code with testbench. Please mention...
a) Design a16-bit MIPS Processor in a simplest form in Verilog code with testbench. Please mention the comments where applicable. b) mention the steps how your design works.
Design a16-bit RISC MIPS Processor. Develop modules, a block diagram, Verilog codes used, and the waveforms...
Design a16-bit RISC MIPS Processor. Develop modules, a block diagram, Verilog codes used, and the waveforms screen-prints.
Design an 8-bit adder. Show Verilog code and testbench.
Design an 8-bit adder. Show Verilog code and testbench.
write the code for 16-bit ALU using vivado. Approach : A hierarchical design approach for 16-bit...
write the code for 16-bit ALU using vivado. Approach : A hierarchical design approach for 16-bit ALU using a Full Adders (16-bit), Multiplier (16-bit), Full Subtractor (16-bit), and shift left A register. include test bench. S0 S1 Alu-operation 0 0 addition 0 1 subtraction 1 0 multiplication 1 1 shift right
Please Create the Verilog/Vivado Code For: An LFSR Pseudonumber generator, and the testbench for test it,...
Please Create the Verilog/Vivado Code For: An LFSR Pseudonumber generator, and the testbench for test it, please comment and explain the answer as much as possible if possible, post Pic of the waveform simulation!
Please Create the Verilog/Vivado Code For: An LFSR Pseudonumber generator, and the testbench for test it,...
Please Create the Verilog/Vivado Code For: An LFSR Pseudonumber generator, and the testbench for test it, please comment and explain the answer as much as possible waveform simulation answer would be nice too!
Please Create the Verilog/Vivado Code For: An LFSR Pseudonumber generator, and the testbench for test it,...
Please Create the Verilog/Vivado Code For: An LFSR Pseudonumber generator, and the testbench for test it, please comment and explain the answer as much as possible!
Please Create the Verilog/Vivado Code For: An LFSR Pseudonumber generator, and the testbench for test it,...
Please Create the Verilog/Vivado Code For: An LFSR Pseudonumber generator, and the testbench for test it, please comment and explain the answer as much as possible,(Make your own code, even it is more simple, but do not copy from others sources on the internet) if possible, post Pic of the waveform simulation!
Write a Verilog code to implement 16 bit LFSR
Write a Verilog code to implement 16 bit LFSR
Design a circuit and write a verilog code description of the 16-bit right rotator using barrel...
Design a circuit and write a verilog code description of the 16-bit right rotator using barrel shift method
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT