forked from Github_Repos/cvw
		
	FPU Assembly tests
This commit is contained in:
		
							parent
							
								
									6be5bb1f84
								
							
						
					
					
						commit
						ec82453ba1
					
				
							
								
								
									
										29
									
								
								wally-pipelined/src/fpu/fcsr.sv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								wally-pipelined/src/fpu/fcsr.sv
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,29 @@
 | 
			
		||||
`include "../../config/rv64icfd/wally-config.vh"
 | 
			
		||||
 | 
			
		||||
module fcsr(
 | 
			
		||||
  input  logic [2:0]       frm,
 | 
			
		||||
  input  logic             reset,
 | 
			
		||||
  input  logic             clear,
 | 
			
		||||
  input  logic             clk,
 | 
			
		||||
  input  logic             write,
 | 
			
		||||
  input  logic [4:0]       flags,
 | 
			
		||||
  output logic [31:0] readData);
 | 
			
		||||
 | 
			
		||||
  //register I/O assignment
 | 
			
		||||
  logic [31:0] regInput;
 | 
			
		||||
  logic [31:0] regOutput;
 | 
			
		||||
 | 
			
		||||
  //no L instruction support
 | 
			
		||||
  //only last 8 bits used for FCSR
 | 
			
		||||
  
 | 
			
		||||
  //latching input to write signal
 | 
			
		||||
  //AND clk and write and remove latch
 | 
			
		||||
  //for clk-based write
 | 
			
		||||
  assign regInput = (write) ? {24'h0,frm,flags} : regInput;
 | 
			
		||||
 | 
			
		||||
  floprc #(32) (.clk(clk), .reset(reset), .clear(clear), .d(regInput), .q(regOutput));
 | 
			
		||||
 | 
			
		||||
  assign readData = regOutput;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
endmodule
 | 
			
		||||
							
								
								
									
										143
									
								
								wally-pipelined/src/fpu/fctrl.sv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										143
									
								
								wally-pipelined/src/fpu/fctrl.sv
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,143 @@
 | 
			
		||||
`include "../../config/rv64icfd/wally-config.vh"
 | 
			
		||||
 | 
			
		||||
module fctrl (
 | 
			
		||||
  input  logic [6:0] Funct7D,
 | 
			
		||||
  input  logic [6:0] OpD,
 | 
			
		||||
  input  logic [4:0] Rs2D,
 | 
			
		||||
  input  logic [4:0] Rs1D,
 | 
			
		||||
  input  logic [2:0] FrmW,
 | 
			
		||||
  output logic       WriteEnD,
 | 
			
		||||
  output logic       DivSqrtStartD,
 | 
			
		||||
  output logic [2:0] regSelD,
 | 
			
		||||
  output logic [2:0] writeSelD,
 | 
			
		||||
  output logic [3:0] OpCtrlD,
 | 
			
		||||
  output logic       FmtD,
 | 
			
		||||
  output logic       WriteIntD);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  //precision is taken directly from instruction
 | 
			
		||||
  assign FmtD = Funct7D[0];
 | 
			
		||||
 | 
			
		||||
  //all subsequent logic is based on the table present
 | 
			
		||||
  //in Section 5 of Wally Architecture Specification
 | 
			
		||||
  
 | 
			
		||||
  //write is enabled for all fp instruciton op codes
 | 
			
		||||
  //sans fp load
 | 
			
		||||
  logic isFP, isFPLD;
 | 
			
		||||
  always_comb begin
 | 
			
		||||
	//case statement is easier to modify
 | 
			
		||||
	//in case of errors
 | 
			
		||||
	case(OpD)
 | 
			
		||||
		//fp instructions sans load
 | 
			
		||||
		7'b1010011 : begin isFP = 1'b1; isFPLD = 1'b0; end
 | 
			
		||||
		7'b1000011 : begin isFP = 1'b1; isFPLD = 1'b0; end
 | 
			
		||||
		7'b1000111 : begin isFP = 1'b1; isFPLD = 1'b0; end
 | 
			
		||||
		7'b1001011 : begin isFP = 1'b1; isFPLD = 1'b0; end
 | 
			
		||||
		7'b1001111 : begin isFP = 1'b1; isFPLD = 1'b0; end
 | 
			
		||||
		7'b0100111 : begin isFP = 1'b1; isFPLD = 1'b0; end
 | 
			
		||||
		//fp load	
 | 
			
		||||
		7'b1010011 : begin isFP = 1'b1; isFPLD = 1'b1; end
 | 
			
		||||
		default : begin isFP = 1'b0; isFPLD = 1'b0; end
 | 
			
		||||
	endcase
 | 
			
		||||
  end
 | 
			
		||||
  
 | 
			
		||||
  assign WriteEnD = isFP & ~isFPLD; 
 | 
			
		||||
  
 | 
			
		||||
  //useful intermediary signals
 | 
			
		||||
  //
 | 
			
		||||
  //(mult only not supported in current datapath)
 | 
			
		||||
  //set third FMA operand to zero in this case
 | 
			
		||||
  //(or equivalent)
 | 
			
		||||
  logic isAddSub, isFMA, isMult, isDivSqrt, isCvt, isCmp, isFPSTR;
 | 
			
		||||
 | 
			
		||||
  always_comb begin
 | 
			
		||||
	//checks all but FMA/store/load
 | 
			
		||||
	if(OpD == 7'b1010011) begin
 | 
			
		||||
  		case(Funct7D)
 | 
			
		||||
			//compare	
 | 
			
		||||
			7'b10100?? : begin isAddSub = 1'b0; isFMA = 1'b0; isMult = 1'b0; isDivSqrt = 1'b0; isCvt = 1'b0; isCmp = 1'b1; isFPSTR = 1'b0; end
 | 
			
		||||
			//div/sqrt
 | 
			
		||||
			7'b0?011?? : begin isAddSub = 1'b0; isFMA = 1'b0; isMult = 1'b0; isDivSqrt = 1'b1; isCvt = 1'b0; isCmp = 1'b0; isFPSTR = 1'b0; end
 | 
			
		||||
			//add/sub
 | 
			
		||||
			7'b0000??? : begin isAddSub = 1'b1; isFMA = 1'b0; isMult = 1'b0; isDivSqrt = 1'b0; isCvt = 1'b0; isCmp = 1'b0; isFPSTR = 1'b0; end
 | 
			
		||||
			//mult
 | 
			
		||||
			7'b00010?? : begin isAddSub = 1'b0; isFMA = 1'b0; isMult = 1'b1; isDivSqrt = 1'b0; isCvt = 1'b0; isCmp = 1'b0; isFPSTR = 1'b0; end
 | 
			
		||||
			//convert (not precision)
 | 
			
		||||
			7'b110?0?? : begin isAddSub = 1'b0; isFMA = 1'b0; isMult = 1'b0; isDivSqrt = 1'b0; isCvt = 1'b1; isCmp = 1'b0; isFPSTR = 1'b0; end
 | 
			
		||||
			//convert (precision)
 | 
			
		||||
			7'b010000? : begin isAddSub = 1'b0; isFMA = 1'b0; isMult = 1'b0; isDivSqrt = 1'b0; isCvt = 1'b1; isCmp = 1'b0; isFPSTR = 1'b0; end
 | 
			
		||||
		endcase
 | 
			
		||||
	end
 | 
			
		||||
	//FMA/store/load
 | 
			
		||||
	else begin
 | 
			
		||||
  		case(OpD)
 | 
			
		||||
			//4 FMA instructions
 | 
			
		||||
			7'b1000011 : begin isAddSub = 1'b0; isFMA = 1'b1; isMult = 1'b0; isDivSqrt = 1'b0; isCvt = 1'b0; isCmp = 1'b0; isFPSTR = 1'b0; end
 | 
			
		||||
			7'b1000111 : begin isAddSub = 1'b0; isFMA = 1'b1; isMult = 1'b0; isDivSqrt = 1'b0; isCvt = 1'b0; isCmp = 1'b0; isFPSTR = 1'b0; end
 | 
			
		||||
			7'b1001011 : begin isAddSub = 1'b0; isFMA = 1'b1; isMult = 1'b0; isDivSqrt = 1'b0; isCvt = 1'b0; isCmp = 1'b0; isFPSTR = 1'b0; end
 | 
			
		||||
			7'b1001111 : begin isAddSub = 1'b0; isFMA = 1'b1; isMult = 1'b0; isDivSqrt = 1'b0; isCvt = 1'b0; isCmp = 1'b0; isFPSTR = 1'b0; end
 | 
			
		||||
			//store (load already found)
 | 
			
		||||
			7'b0100111 : begin isAddSub = 1'b0; isFMA = 1'b0; isMult = 1'b0; isDivSqrt = 1'b0; isCvt = 1'b0; isCmp = 1'b0; isFPSTR = 1'b1; end
 | 
			
		||||
		endcase
 | 
			
		||||
	end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  //register is chosen based on operation performed
 | 
			
		||||
  //---- 
 | 
			
		||||
  //write selection is chosen in the same way as 
 | 
			
		||||
  //register selection
 | 
			
		||||
  //
 | 
			
		||||
 | 
			
		||||
  // reg/write sel logic and assignment
 | 
			
		||||
  // 
 | 
			
		||||
  // 3'b000 = add/sub/cvt
 | 
			
		||||
  // 3'b001 = sign
 | 
			
		||||
  // 3'b010 = fma
 | 
			
		||||
  // 3'b011 = cmp
 | 
			
		||||
  // 3'b100 = div/sqrt
 | 
			
		||||
  //
 | 
			
		||||
  //reg select
 | 
			
		||||
  
 | 
			
		||||
  //this value is used enough to be shorthand
 | 
			
		||||
  logic isSign;
 | 
			
		||||
  assign isSign = ~Funct7D[6] & ~Funct7D[5] & Funct7D[4] & ~Funct7D[3] & ~Funct7D[2];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  assign regSelD[2] = isDivSqrt & ~isFMA;
 | 
			
		||||
  assign regSelD[1] = isFMA | isCmp;
 | 
			
		||||
  //AND of Funct7 for sign
 | 
			
		||||
  assign regSelD[0] = isCmp | isSign;
 | 
			
		||||
 | 
			
		||||
  //write select
 | 
			
		||||
  assign writeSelD[2] = isDivSqrt & ~isFMA;
 | 
			
		||||
  assign writeSelD[1] = isFMA | isCmp;
 | 
			
		||||
  //AND of Funct7 for sign
 | 
			
		||||
  assign writeSelD[0] = isCmp | isSign;
 | 
			
		||||
 | 
			
		||||
  //if op is div/sqrt - start div/sqrt
 | 
			
		||||
  assign DivSqrtStartD = isDivSqrt & ~isFMA;
 | 
			
		||||
 | 
			
		||||
  //operation control for each fp operation
 | 
			
		||||
  //has to be expanded over standard to account for
 | 
			
		||||
  //integrated fpadd/cvt
 | 
			
		||||
  //
 | 
			
		||||
  //will integrate FMA opcodes into design later
 | 
			
		||||
  //
 | 
			
		||||
  //conversion instructions will
 | 
			
		||||
  //also need to be added later as I find the opcode
 | 
			
		||||
  //version I used for this repo
 | 
			
		||||
 | 
			
		||||
  assign OpCtrlD[3] = 1'b0;
 | 
			
		||||
  //if is positive sign injection OR is precision convert
 | 
			
		||||
  assign OpCtrlD[2] = (isSign & ~FrmW[0]) | (~Funct7D[6] & Funct7D[5] & ~Funct7D[4] & ~Funct7D[3] & ~Funct7D[2] & ~Funct7D[1]);
 | 
			
		||||
  //if is precision convert OR is sign xor 
 | 
			
		||||
  assign OpCtrlD[1] = (isSign & FrmW[1]) | (~Funct7D[6] & Funct7D[5] & ~Funct7D[4] & ~Funct7D[3] & ~Funct7D[2] & ~Funct7D[1]);
 | 
			
		||||
  //if is sqrt OR is sub OR is single-precision cmp OR negation
 | 
			
		||||
  assign OpCtrlD[0] = (isDivSqrt & ~isFMA & Funct7D[6]) | (isAddSub & ~isFMA & Funct7D[2]) | (isCmp & ~isFMA & Funct7D[0]) | (isSign & FrmW[0]);
 | 
			
		||||
  
 | 
			
		||||
  //write to integer source if conv to int occurs
 | 
			
		||||
  //AND of Funct7 for int results 
 | 
			
		||||
  assign WriteIntD = isCvt & (Funct7D[6] & Funct7D[5] & ~Funct7D[4] & ~Funct7D[3] & ~Funct7D[2] & ~Funct7D[1]);
 | 
			
		||||
 | 
			
		||||
endmodule
 | 
			
		||||
							
								
								
									
										59
									
								
								wally-pipelined/src/fpu/fputop.sv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								wally-pipelined/src/fpu/fputop.sv
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,59 @@
 | 
			
		||||
`include "../../config/rv64icfd/wally-config.vh"
 | 
			
		||||
 | 
			
		||||
module fputop (
 | 
			
		||||
  input  logic [2:0]       FrmW,
 | 
			
		||||
  input  logic             reset,
 | 
			
		||||
  input  logic             clear,
 | 
			
		||||
  input  logic             clk,
 | 
			
		||||
  input  logic [31:0]      InstrD,
 | 
			
		||||
  input  logic [`XLEN-1:0] SrcAE,
 | 
			
		||||
  input  logic [`XLEN-1:0] SrcAW,
 | 
			
		||||
  output logic [31:0]      FSROutW,
 | 
			
		||||
  output logic             DivSqrtDoneE,
 | 
			
		||||
  output logic             FInvalInstrD,
 | 
			
		||||
  output logic [`XLEN-1:0] FPUResultW);
 | 
			
		||||
 
 | 
			
		||||
  /*fctrl ();
 | 
			
		||||
 | 
			
		||||
  //regfile instantiation and decode stage
 | 
			
		||||
  //freg1adr ();
 | 
			
		||||
  
 | 
			
		||||
  //freg2adr ();
 | 
			
		||||
  
 | 
			
		||||
  //freg2adr ();
 | 
			
		||||
 | 
			
		||||
  //freg2adr ();
 | 
			
		||||
 | 
			
		||||
  freg3adr ();
 | 
			
		||||
 | 
			
		||||
  //can easily be merged into privledged core
 | 
			
		||||
  //if necessary
 | 
			
		||||
  //fcsr ();
 | 
			
		||||
 | 
			
		||||
  //E pipe and execution stage
 | 
			
		||||
 
 | 
			
		||||
  fpdivsqrt ();
 | 
			
		||||
 | 
			
		||||
  fma1 ();
 | 
			
		||||
 | 
			
		||||
  fpaddcvt1 ();
 | 
			
		||||
 | 
			
		||||
  fpcmp1 ();
 | 
			
		||||
 | 
			
		||||
  fpsign ();
 | 
			
		||||
 | 
			
		||||
  //M pipe and memory stage 
 | 
			
		||||
 | 
			
		||||
  fma2 ();
 | 
			
		||||
 | 
			
		||||
  fpaddcvt2 ();
 | 
			
		||||
 | 
			
		||||
  fpcmp2 ();
 | 
			
		||||
 | 
			
		||||
  //W pipe and writeback stage
 | 
			
		||||
 | 
			
		||||
  //flag signal mux
 | 
			
		||||
  
 | 
			
		||||
  //result mux
 | 
			
		||||
*/
 | 
			
		||||
endmodule
 | 
			
		||||
							
								
								
									
										513
									
								
								wally-pipelined/src/fpu/freg.sv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										513
									
								
								wally-pipelined/src/fpu/freg.sv
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,513 @@
 | 
			
		||||
`include "../../config/rv64icfd/wally-config.vh"
 | 
			
		||||
 | 
			
		||||
module freg1adr (
 | 
			
		||||
  input  logic [2:0]       frm,
 | 
			
		||||
  input  logic             reset,
 | 
			
		||||
  input  logic             clear,
 | 
			
		||||
  input  logic             clk,
 | 
			
		||||
  input  logic [4:0]       rd,
 | 
			
		||||
  input  logic             write,
 | 
			
		||||
  input  logic [4:0]       adr1,
 | 
			
		||||
  input  logic [`XLEN-1:0] writeData,
 | 
			
		||||
  output logic [`XLEN-1:0] readData);
 | 
			
		||||
 | 
			
		||||
  //note - not word aligning based on precision of 
 | 
			
		||||
  //operation (frm)
 | 
			
		||||
 | 
			
		||||
  //reg number should remain static, but it doesn't hurt
 | 
			
		||||
  //to parameterize
 | 
			
		||||
  parameter numRegs = 32;
 | 
			
		||||
 | 
			
		||||
  //intermediary signals - useful for debugging
 | 
			
		||||
  //and easy instatiation of generated modules
 | 
			
		||||
  logic [`XLEN-1:0] [numRegs-1:0] regInput;
 | 
			
		||||
  logic [`XLEN-1:0] [numRegs-1:0] regOutput;
 | 
			
		||||
 | 
			
		||||
  //generate fp registers themselves
 | 
			
		||||
  genvar i;
 | 
			
		||||
  generate
 | 
			
		||||
  	for (i = 0; i < numRegs; i = i + 1) begin:register
 | 
			
		||||
 | 
			
		||||
  		floprc #(`XLEN) (.clk(clk), .reset(reset), .clear(clear), .d(regInput[i][`XLEN-1:0]), .q(regOutput[i][`XLEN-1:0])); 
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
  endgenerate
 | 
			
		||||
 | 
			
		||||
  //this could be done with:
 | 
			
		||||
  //
 | 
			
		||||
  //assign readData = regOutput[adr1];
 | 
			
		||||
  //
 | 
			
		||||
  //but always_comb allows for finer control
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  //address decoder
 | 
			
		||||
  //only 1 for this fp register set
 | 
			
		||||
  //used with fpsign
 | 
			
		||||
  //defaults to outputting zeroes
 | 
			
		||||
  always_comb begin
 | 
			
		||||
  	case(adr1)
 | 
			
		||||
		5'b00000 : readData = regOutput[0];
 | 
			
		||||
		5'b00001 : readData = regOutput[1];
 | 
			
		||||
		5'b00010 : readData = regOutput[2];
 | 
			
		||||
		5'b00011 : readData = regOutput[3];
 | 
			
		||||
		5'b00100 : readData = regOutput[4];
 | 
			
		||||
		5'b00101 : readData = regOutput[5];
 | 
			
		||||
		5'b00110 : readData = regOutput[6];
 | 
			
		||||
		5'b00111 : readData = regOutput[7];
 | 
			
		||||
		5'b01000 : readData = regOutput[8];
 | 
			
		||||
		5'b01001 : readData = regOutput[9];
 | 
			
		||||
		5'b01010 : readData = regOutput[10];
 | 
			
		||||
		5'b01011 : readData = regOutput[11];
 | 
			
		||||
		5'b01100 : readData = regOutput[12];
 | 
			
		||||
		5'b01101 : readData = regOutput[13];
 | 
			
		||||
		5'b01110 : readData = regOutput[14];
 | 
			
		||||
		5'b01111 : readData = regOutput[15];
 | 
			
		||||
		5'b10000 : readData = regOutput[16];
 | 
			
		||||
		5'b10001 : readData = regOutput[17];
 | 
			
		||||
		5'b10010 : readData = regOutput[18];
 | 
			
		||||
		5'b10011 : readData = regOutput[19];
 | 
			
		||||
		5'b10100 : readData = regOutput[20];
 | 
			
		||||
		5'b10101 : readData = regOutput[21];
 | 
			
		||||
		5'b10110 : readData = regOutput[22];
 | 
			
		||||
		5'b10111 : readData = regOutput[23];
 | 
			
		||||
		5'b11000 : readData = regOutput[24];
 | 
			
		||||
		5'b11001 : readData = regOutput[25];
 | 
			
		||||
		5'b11010 : readData = regOutput[26];
 | 
			
		||||
		5'b11011 : readData = regOutput[27];
 | 
			
		||||
		5'b11100 : readData = regOutput[28];
 | 
			
		||||
		5'b11101 : readData = regOutput[29];
 | 
			
		||||
		5'b11110 : readData = regOutput[30];
 | 
			
		||||
		5'b11111 : readData = regOutput[31];
 | 
			
		||||
		default : readData = `XLEN'h0;
 | 
			
		||||
	endcase
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  //destination register decoder
 | 
			
		||||
  //only change input values on write
 | 
			
		||||
  //defaults to undefined with invalid address
 | 
			
		||||
  //
 | 
			
		||||
  //note - this is an intermediary signal, so
 | 
			
		||||
  //this is not asynch assignment. FF in flopr
 | 
			
		||||
  //will not update data until clk pulse
 | 
			
		||||
  always_comb begin
 | 
			
		||||
	  if(write) begin
 | 
			
		||||
		case(rd)	
 | 
			
		||||
			5'b00000 : regInput[0] = writeData;
 | 
			
		||||
			5'b00001 : regInput[1] = writeData;
 | 
			
		||||
			5'b00010 : regInput[2] = writeData;
 | 
			
		||||
			5'b00011 : regInput[3] = writeData;	
 | 
			
		||||
			5'b00100 : regInput[4] = writeData;
 | 
			
		||||
			5'b00101 : regInput[5] = writeData;
 | 
			
		||||
			5'b00110 : regInput[6] = writeData;
 | 
			
		||||
			5'b00111 : regInput[7] = writeData;
 | 
			
		||||
			5'b01000 : regInput[8] = writeData;
 | 
			
		||||
			5'b01000 : regInput[9] = writeData;
 | 
			
		||||
			5'b01001 : regInput[10] = writeData;
 | 
			
		||||
			5'b01010 : regInput[11] = writeData;
 | 
			
		||||
			5'b01111 : regInput[12] = writeData;
 | 
			
		||||
			5'b01101 : regInput[13] = writeData;
 | 
			
		||||
			5'b01110 : regInput[14] = writeData;
 | 
			
		||||
			5'b01111 : regInput[15] = writeData;
 | 
			
		||||
			5'b10000 : regInput[16] = writeData;
 | 
			
		||||
			5'b10001 : regInput[17] = writeData;
 | 
			
		||||
			5'b10010 : regInput[18] = writeData;
 | 
			
		||||
			5'b10011 : regInput[19] = writeData;	
 | 
			
		||||
			5'b10100 : regInput[20] = writeData;
 | 
			
		||||
			5'b10101 : regInput[21] = writeData;
 | 
			
		||||
			5'b10110 : regInput[22] = writeData;
 | 
			
		||||
			5'b10111 : regInput[23] = writeData;
 | 
			
		||||
			5'b11000 : regInput[24] = writeData;
 | 
			
		||||
			5'b11000 : regInput[25] = writeData;
 | 
			
		||||
			5'b11001 : regInput[26] = writeData;
 | 
			
		||||
			5'b11010 : regInput[27] = writeData;
 | 
			
		||||
			5'b11111 : regInput[28] = writeData;
 | 
			
		||||
			5'b11101 : regInput[29] = writeData;
 | 
			
		||||
			5'b11110 : regInput[30] = writeData;
 | 
			
		||||
			5'b11111 : regInput[31] = writeData;
 | 
			
		||||
			default : regInput[0] = `XLEN'hx;
 | 
			
		||||
		endcase
 | 
			
		||||
	end	
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
//********
 | 
			
		||||
//formatting separation
 | 
			
		||||
//********
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
module freg2adr (
 | 
			
		||||
  input  logic [2:0]       frm,
 | 
			
		||||
  input  logic             reset,
 | 
			
		||||
  input  logic             clear,
 | 
			
		||||
  input  logic             clk,
 | 
			
		||||
  input  logic [4:0]       rd,
 | 
			
		||||
  input  logic             write,
 | 
			
		||||
  input  logic [4:0]       adr1,
 | 
			
		||||
  input  logic [4:0]       adr2,
 | 
			
		||||
  input  logic [`XLEN-1:0] writeData,
 | 
			
		||||
  output logic [`XLEN-1:0] readData1,
 | 
			
		||||
  output logic [`XLEN-1:0] readData2);
 | 
			
		||||
 | 
			
		||||
  //note - not word aligning based on precision of 
 | 
			
		||||
  //operation (frm)
 | 
			
		||||
 | 
			
		||||
  //reg number should remain static, but it doesn't hurt
 | 
			
		||||
  //to parameterize
 | 
			
		||||
  parameter numRegs = 32;
 | 
			
		||||
 | 
			
		||||
  //intermediary signals - useful for debugging
 | 
			
		||||
  //and easy instatiation of generated modules
 | 
			
		||||
  logic [`XLEN-1:0] [numRegs-1:0] regInput;
 | 
			
		||||
  logic [`XLEN-1:0] [numRegs-1:0] regOutput;
 | 
			
		||||
 | 
			
		||||
  //generate fp registers themselves
 | 
			
		||||
  genvar i;
 | 
			
		||||
  generate
 | 
			
		||||
  	for (i = 0; i < numRegs; i = i + 1) begin:register
 | 
			
		||||
 | 
			
		||||
  		floprc #(`XLEN) (.clk(clk), .reset(reset), .clear(clear), .d(regInput[i][`XLEN-1:0]), .q(regOutput[i][`XLEN-1:0])); 
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
  endgenerate
 | 
			
		||||
 | 
			
		||||
  //address decoder
 | 
			
		||||
  //2 are used for this fp register set
 | 
			
		||||
  //used with fpadd/cvt, fpdiv/sqrt, and fpcmp
 | 
			
		||||
  //defaults to outputting zeroes
 | 
			
		||||
  always_comb begin
 | 
			
		||||
 | 
			
		||||
	//adderss 1 decoder
 | 
			
		||||
  	case(adr1)
 | 
			
		||||
		5'b00000 : readData1 = regOutput[0];
 | 
			
		||||
		5'b00001 : readData1 = regOutput[1];
 | 
			
		||||
		5'b00010 : readData1 = regOutput[2];
 | 
			
		||||
		5'b00011 : readData1 = regOutput[3];
 | 
			
		||||
		5'b00100 : readData1 = regOutput[4];
 | 
			
		||||
		5'b00101 : readData1 = regOutput[5];
 | 
			
		||||
		5'b00110 : readData1 = regOutput[6];
 | 
			
		||||
		5'b00111 : readData1 = regOutput[7];
 | 
			
		||||
		5'b01000 : readData1 = regOutput[8];
 | 
			
		||||
		5'b01001 : readData1 = regOutput[9];
 | 
			
		||||
		5'b01010 : readData1 = regOutput[10];
 | 
			
		||||
		5'b01011 : readData1 = regOutput[11];
 | 
			
		||||
		5'b01100 : readData1 = regOutput[12];
 | 
			
		||||
		5'b01101 : readData1 = regOutput[13];
 | 
			
		||||
		5'b01110 : readData1 = regOutput[14];
 | 
			
		||||
		5'b01111 : readData1 = regOutput[15];
 | 
			
		||||
		5'b10000 : readData1 = regOutput[16];
 | 
			
		||||
		5'b10001 : readData1 = regOutput[17];
 | 
			
		||||
		5'b10010 : readData1 = regOutput[18];
 | 
			
		||||
		5'b10011 : readData1 = regOutput[19];
 | 
			
		||||
		5'b10100 : readData1 = regOutput[20];
 | 
			
		||||
		5'b10101 : readData1 = regOutput[21];
 | 
			
		||||
		5'b10110 : readData1 = regOutput[22];
 | 
			
		||||
		5'b10111 : readData1 = regOutput[23];
 | 
			
		||||
		5'b11000 : readData1 = regOutput[24];
 | 
			
		||||
		5'b11001 : readData1 = regOutput[25];
 | 
			
		||||
		5'b11010 : readData1 = regOutput[26];
 | 
			
		||||
		5'b11011 : readData1 = regOutput[27];
 | 
			
		||||
		5'b11100 : readData1 = regOutput[28];
 | 
			
		||||
		5'b11101 : readData1 = regOutput[29];
 | 
			
		||||
		5'b11110 : readData1 = regOutput[30];
 | 
			
		||||
		5'b11111 : readData1 = regOutput[31];
 | 
			
		||||
		default : readData1 = `XLEN'h0;
 | 
			
		||||
	endcase
 | 
			
		||||
 | 
			
		||||
	//address 2 decoder
 | 
			
		||||
  	case(adr2)
 | 
			
		||||
		5'b00000 : readData2 = regOutput[0];
 | 
			
		||||
		5'b00001 : readData2 = regOutput[1];
 | 
			
		||||
		5'b00010 : readData2 = regOutput[2];
 | 
			
		||||
		5'b00011 : readData2 = regOutput[3];
 | 
			
		||||
		5'b00100 : readData2 = regOutput[4];
 | 
			
		||||
		5'b00101 : readData2 = regOutput[5];
 | 
			
		||||
		5'b00110 : readData2 = regOutput[6];
 | 
			
		||||
		5'b00111 : readData2 = regOutput[7];
 | 
			
		||||
		5'b01000 : readData2 = regOutput[8];
 | 
			
		||||
		5'b01001 : readData2 = regOutput[9];
 | 
			
		||||
		5'b01010 : readData2 = regOutput[10];
 | 
			
		||||
		5'b01011 : readData2 = regOutput[11];
 | 
			
		||||
		5'b01100 : readData2 = regOutput[12];
 | 
			
		||||
		5'b01101 : readData2 = regOutput[13];
 | 
			
		||||
		5'b01110 : readData2 = regOutput[14];
 | 
			
		||||
		5'b01111 : readData2 = regOutput[15];
 | 
			
		||||
		5'b10000 : readData2 = regOutput[16];
 | 
			
		||||
		5'b10001 : readData2 = regOutput[17];
 | 
			
		||||
		5'b10010 : readData2 = regOutput[18];
 | 
			
		||||
		5'b10011 : readData2 = regOutput[19];
 | 
			
		||||
		5'b10100 : readData2 = regOutput[20];
 | 
			
		||||
		5'b10101 : readData2 = regOutput[21];
 | 
			
		||||
		5'b10110 : readData2 = regOutput[22];
 | 
			
		||||
		5'b10111 : readData2 = regOutput[23];
 | 
			
		||||
		5'b11000 : readData2 = regOutput[24];
 | 
			
		||||
		5'b11001 : readData2 = regOutput[25];
 | 
			
		||||
		5'b11010 : readData2 = regOutput[26];
 | 
			
		||||
		5'b11011 : readData2 = regOutput[27];
 | 
			
		||||
		5'b11100 : readData2 = regOutput[28];
 | 
			
		||||
		5'b11101 : readData2 = regOutput[29];
 | 
			
		||||
		5'b11110 : readData2 = regOutput[30];
 | 
			
		||||
		5'b11111 : readData2 = regOutput[31];
 | 
			
		||||
		default : readData2 = `XLEN'h0;
 | 
			
		||||
	endcase
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  //destination register decoder
 | 
			
		||||
  //only change input values on write
 | 
			
		||||
  //defaults to undefined with invalid address
 | 
			
		||||
  //
 | 
			
		||||
  //note - this is an intermediary signal, so
 | 
			
		||||
  //this is not asynch assignment. FF in flopr
 | 
			
		||||
  //will not update data until clk pulse
 | 
			
		||||
  always_comb begin
 | 
			
		||||
	  if(write) begin
 | 
			
		||||
		case(rd)	
 | 
			
		||||
			5'b00000 : regInput[0] = writeData;
 | 
			
		||||
			5'b00001 : regInput[1] = writeData;
 | 
			
		||||
			5'b00010 : regInput[2] = writeData;
 | 
			
		||||
			5'b00011 : regInput[3] = writeData;	
 | 
			
		||||
			5'b00100 : regInput[4] = writeData;
 | 
			
		||||
			5'b00101 : regInput[5] = writeData;
 | 
			
		||||
			5'b00110 : regInput[6] = writeData;
 | 
			
		||||
			5'b00111 : regInput[7] = writeData;
 | 
			
		||||
			5'b01000 : regInput[8] = writeData;
 | 
			
		||||
			5'b01000 : regInput[9] = writeData;
 | 
			
		||||
			5'b01001 : regInput[10] = writeData;
 | 
			
		||||
			5'b01010 : regInput[11] = writeData;
 | 
			
		||||
			5'b01111 : regInput[12] = writeData;
 | 
			
		||||
			5'b01101 : regInput[13] = writeData;
 | 
			
		||||
			5'b01110 : regInput[14] = writeData;
 | 
			
		||||
			5'b01111 : regInput[15] = writeData;
 | 
			
		||||
			5'b10000 : regInput[16] = writeData;
 | 
			
		||||
			5'b10001 : regInput[17] = writeData;
 | 
			
		||||
			5'b10010 : regInput[18] = writeData;
 | 
			
		||||
			5'b10011 : regInput[19] = writeData;	
 | 
			
		||||
			5'b10100 : regInput[20] = writeData;
 | 
			
		||||
			5'b10101 : regInput[21] = writeData;
 | 
			
		||||
			5'b10110 : regInput[22] = writeData;
 | 
			
		||||
			5'b10111 : regInput[23] = writeData;
 | 
			
		||||
			5'b11000 : regInput[24] = writeData;
 | 
			
		||||
			5'b11000 : regInput[25] = writeData;
 | 
			
		||||
			5'b11001 : regInput[26] = writeData;
 | 
			
		||||
			5'b11010 : regInput[27] = writeData;
 | 
			
		||||
			5'b11111 : regInput[28] = writeData;
 | 
			
		||||
			5'b11101 : regInput[29] = writeData;
 | 
			
		||||
			5'b11110 : regInput[30] = writeData;
 | 
			
		||||
			5'b11111 : regInput[31] = writeData;
 | 
			
		||||
			default : regInput[0] = `XLEN'hx;
 | 
			
		||||
		endcase
 | 
			
		||||
	end	
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
//********
 | 
			
		||||
//formatting separation
 | 
			
		||||
//********
 | 
			
		||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
module freg3adr (
 | 
			
		||||
  input  logic [2:0]       frm,
 | 
			
		||||
  input  logic             reset,
 | 
			
		||||
  input  logic             clear,
 | 
			
		||||
  input  logic             clk,
 | 
			
		||||
  input  logic [4:0]       rd,
 | 
			
		||||
  input  logic             write,
 | 
			
		||||
  input  logic [4:0]       adr1,
 | 
			
		||||
  input  logic [4:0]       adr2,
 | 
			
		||||
  input  logic [4:0]       adr3,
 | 
			
		||||
  input  logic [`XLEN-1:0] writeData,
 | 
			
		||||
  output logic [`XLEN-1:0] readData1,
 | 
			
		||||
  output logic [`XLEN-1:0] readData2,
 | 
			
		||||
  output logic [`XLEN-1:0] readData3);
 | 
			
		||||
 | 
			
		||||
  //note - not word aligning based on precision of 
 | 
			
		||||
  //operation (frm)
 | 
			
		||||
 | 
			
		||||
  //reg number should remain static, but it doesn't hurt
 | 
			
		||||
  //to parameterize
 | 
			
		||||
  parameter numRegs = 32;
 | 
			
		||||
 | 
			
		||||
  //intermediary signals - useful for debugging
 | 
			
		||||
  //and easy instatiation of generated modules
 | 
			
		||||
  logic [`XLEN-1:0] [numRegs-1:0] regInput;
 | 
			
		||||
  logic [`XLEN-1:0] [numRegs-1:0] regOutput;
 | 
			
		||||
 | 
			
		||||
  //generate fp registers themselves
 | 
			
		||||
  genvar i;
 | 
			
		||||
  generate
 | 
			
		||||
  	for (i = 0; i < numRegs; i = i + 1) begin:register
 | 
			
		||||
 | 
			
		||||
  		floprc #(`XLEN) (.clk(clk), .reset(reset), .clear(clear), .d(regInput[i][`XLEN-1:0]), .q(regOutput[i][`XLEN-1:0])); 
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
  endgenerate
 | 
			
		||||
 | 
			
		||||
  //address decoder
 | 
			
		||||
  //3 are used for this fp register set
 | 
			
		||||
  //used exclusively for fma
 | 
			
		||||
  //defaults to outputting zeroes
 | 
			
		||||
  always_comb begin
 | 
			
		||||
 | 
			
		||||
	//adderss 1 decoder
 | 
			
		||||
  	case(adr1)
 | 
			
		||||
		5'b00000 : readData1 = regOutput[0];
 | 
			
		||||
		5'b00001 : readData1 = regOutput[1];
 | 
			
		||||
		5'b00010 : readData1 = regOutput[2];
 | 
			
		||||
		5'b00011 : readData1 = regOutput[3];
 | 
			
		||||
		5'b00100 : readData1 = regOutput[4];
 | 
			
		||||
		5'b00101 : readData1 = regOutput[5];
 | 
			
		||||
		5'b00110 : readData1 = regOutput[6];
 | 
			
		||||
		5'b00111 : readData1 = regOutput[7];
 | 
			
		||||
		5'b01000 : readData1 = regOutput[8];
 | 
			
		||||
		5'b01001 : readData1 = regOutput[9];
 | 
			
		||||
		5'b01010 : readData1 = regOutput[10];
 | 
			
		||||
		5'b01011 : readData1 = regOutput[11];
 | 
			
		||||
		5'b01100 : readData1 = regOutput[12];
 | 
			
		||||
		5'b01101 : readData1 = regOutput[13];
 | 
			
		||||
		5'b01110 : readData1 = regOutput[14];
 | 
			
		||||
		5'b01111 : readData1 = regOutput[15];
 | 
			
		||||
		5'b10000 : readData1 = regOutput[16];
 | 
			
		||||
		5'b10001 : readData1 = regOutput[17];
 | 
			
		||||
		5'b10010 : readData1 = regOutput[18];
 | 
			
		||||
		5'b10011 : readData1 = regOutput[19];
 | 
			
		||||
		5'b10100 : readData1 = regOutput[20];
 | 
			
		||||
		5'b10101 : readData1 = regOutput[21];
 | 
			
		||||
		5'b10110 : readData1 = regOutput[22];
 | 
			
		||||
		5'b10111 : readData1 = regOutput[23];
 | 
			
		||||
		5'b11000 : readData1 = regOutput[24];
 | 
			
		||||
		5'b11001 : readData1 = regOutput[25];
 | 
			
		||||
		5'b11010 : readData1 = regOutput[26];
 | 
			
		||||
		5'b11011 : readData1 = regOutput[27];
 | 
			
		||||
		5'b11100 : readData1 = regOutput[28];
 | 
			
		||||
		5'b11101 : readData1 = regOutput[29];
 | 
			
		||||
		5'b11110 : readData1 = regOutput[30];
 | 
			
		||||
		5'b11111 : readData1 = regOutput[31];
 | 
			
		||||
		default : readData1 = `XLEN'h0;
 | 
			
		||||
	endcase
 | 
			
		||||
 | 
			
		||||
	//address 2 decoder
 | 
			
		||||
  	case(adr2)
 | 
			
		||||
		5'b00000 : readData2 = regOutput[0];
 | 
			
		||||
		5'b00001 : readData2 = regOutput[1];
 | 
			
		||||
		5'b00010 : readData2 = regOutput[2];
 | 
			
		||||
		5'b00011 : readData2 = regOutput[3];
 | 
			
		||||
		5'b00100 : readData2 = regOutput[4];
 | 
			
		||||
		5'b00101 : readData2 = regOutput[5];
 | 
			
		||||
		5'b00110 : readData2 = regOutput[6];
 | 
			
		||||
		5'b00111 : readData2 = regOutput[7];
 | 
			
		||||
		5'b01000 : readData2 = regOutput[8];
 | 
			
		||||
		5'b01001 : readData2 = regOutput[9];
 | 
			
		||||
		5'b01010 : readData2 = regOutput[10];
 | 
			
		||||
		5'b01011 : readData2 = regOutput[11];
 | 
			
		||||
		5'b01100 : readData2 = regOutput[12];
 | 
			
		||||
		5'b01101 : readData2 = regOutput[13];
 | 
			
		||||
		5'b01110 : readData2 = regOutput[14];
 | 
			
		||||
		5'b01111 : readData2 = regOutput[15];
 | 
			
		||||
		5'b10000 : readData2 = regOutput[16];
 | 
			
		||||
		5'b10001 : readData2 = regOutput[17];
 | 
			
		||||
		5'b10010 : readData2 = regOutput[18];
 | 
			
		||||
		5'b10011 : readData2 = regOutput[19];
 | 
			
		||||
		5'b10100 : readData2 = regOutput[20];
 | 
			
		||||
		5'b10101 : readData2 = regOutput[21];
 | 
			
		||||
		5'b10110 : readData2 = regOutput[22];
 | 
			
		||||
		5'b10111 : readData2 = regOutput[23];
 | 
			
		||||
		5'b11000 : readData2 = regOutput[24];
 | 
			
		||||
		5'b11001 : readData2 = regOutput[25];
 | 
			
		||||
		5'b11010 : readData2 = regOutput[26];
 | 
			
		||||
		5'b11011 : readData2 = regOutput[27];
 | 
			
		||||
		5'b11100 : readData2 = regOutput[28];
 | 
			
		||||
		5'b11101 : readData2 = regOutput[29];
 | 
			
		||||
		5'b11110 : readData2 = regOutput[30];
 | 
			
		||||
		5'b11111 : readData2 = regOutput[31];
 | 
			
		||||
		default : readData2 = `XLEN'h0;
 | 
			
		||||
	endcase
 | 
			
		||||
 | 
			
		||||
	//address 3 decoder
 | 
			
		||||
  	case(adr3)
 | 
			
		||||
		5'b00000 : readData3 = regOutput[0];
 | 
			
		||||
		5'b00001 : readData3 = regOutput[1];
 | 
			
		||||
		5'b00010 : readData3 = regOutput[2];
 | 
			
		||||
		5'b00011 : readData3 = regOutput[3];
 | 
			
		||||
		5'b00100 : readData3 = regOutput[4];
 | 
			
		||||
		5'b00101 : readData3 = regOutput[5];
 | 
			
		||||
		5'b00110 : readData3 = regOutput[6];
 | 
			
		||||
		5'b00111 : readData3 = regOutput[7];
 | 
			
		||||
		5'b01000 : readData3 = regOutput[8];
 | 
			
		||||
		5'b01001 : readData3 = regOutput[9];
 | 
			
		||||
		5'b01010 : readData3 = regOutput[10];
 | 
			
		||||
		5'b01011 : readData3 = regOutput[11];
 | 
			
		||||
		5'b01100 : readData3 = regOutput[12];
 | 
			
		||||
		5'b01101 : readData3 = regOutput[13];
 | 
			
		||||
		5'b01110 : readData3 = regOutput[14];
 | 
			
		||||
		5'b01111 : readData3 = regOutput[15];
 | 
			
		||||
		5'b10000 : readData3 = regOutput[16];
 | 
			
		||||
		5'b10001 : readData3 = regOutput[17];
 | 
			
		||||
		5'b10010 : readData3 = regOutput[18];
 | 
			
		||||
		5'b10011 : readData3 = regOutput[19];
 | 
			
		||||
		5'b10100 : readData3 = regOutput[20];
 | 
			
		||||
		5'b10101 : readData3 = regOutput[21];
 | 
			
		||||
		5'b10110 : readData3 = regOutput[22];
 | 
			
		||||
		5'b10111 : readData3 = regOutput[23];
 | 
			
		||||
		5'b11000 : readData3 = regOutput[24];
 | 
			
		||||
		5'b11001 : readData3 = regOutput[25];
 | 
			
		||||
		5'b11010 : readData3 = regOutput[26];
 | 
			
		||||
		5'b11011 : readData3 = regOutput[27];
 | 
			
		||||
		5'b11100 : readData3 = regOutput[28];
 | 
			
		||||
		5'b11101 : readData3 = regOutput[29];
 | 
			
		||||
		5'b11110 : readData3 = regOutput[30];
 | 
			
		||||
		5'b11111 : readData3 = regOutput[31];
 | 
			
		||||
		default : readData3 = `XLEN'h0;
 | 
			
		||||
	endcase
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  //destination register decoder
 | 
			
		||||
  //only change input values on write
 | 
			
		||||
  //defaults to undefined with invalid address
 | 
			
		||||
  //
 | 
			
		||||
  //note - this is an intermediary signal, so
 | 
			
		||||
  //this is not asynch assignment. FF in flopr
 | 
			
		||||
  //will not update data until clk pulse
 | 
			
		||||
  always_comb begin
 | 
			
		||||
	  if(write) begin
 | 
			
		||||
		case(rd)	
 | 
			
		||||
			5'b00000 : regInput[0] = writeData;
 | 
			
		||||
			5'b00001 : regInput[1] = writeData;
 | 
			
		||||
			5'b00010 : regInput[2] = writeData;
 | 
			
		||||
			5'b00011 : regInput[3] = writeData;	
 | 
			
		||||
			5'b00100 : regInput[4] = writeData;
 | 
			
		||||
			5'b00101 : regInput[5] = writeData;
 | 
			
		||||
			5'b00110 : regInput[6] = writeData;
 | 
			
		||||
			5'b00111 : regInput[7] = writeData;
 | 
			
		||||
			5'b01000 : regInput[8] = writeData;
 | 
			
		||||
			5'b01000 : regInput[9] = writeData;
 | 
			
		||||
			5'b01001 : regInput[10] = writeData;
 | 
			
		||||
			5'b01010 : regInput[11] = writeData;
 | 
			
		||||
			5'b01111 : regInput[12] = writeData;
 | 
			
		||||
			5'b01101 : regInput[13] = writeData;
 | 
			
		||||
			5'b01110 : regInput[14] = writeData;
 | 
			
		||||
			5'b01111 : regInput[15] = writeData;
 | 
			
		||||
			5'b10000 : regInput[16] = writeData;
 | 
			
		||||
			5'b10001 : regInput[17] = writeData;
 | 
			
		||||
			5'b10010 : regInput[18] = writeData;
 | 
			
		||||
			5'b10011 : regInput[19] = writeData;	
 | 
			
		||||
			5'b10100 : regInput[20] = writeData;
 | 
			
		||||
			5'b10101 : regInput[21] = writeData;
 | 
			
		||||
			5'b10110 : regInput[22] = writeData;
 | 
			
		||||
			5'b10111 : regInput[23] = writeData;
 | 
			
		||||
			5'b11000 : regInput[24] = writeData;
 | 
			
		||||
			5'b11000 : regInput[25] = writeData;
 | 
			
		||||
			5'b11001 : regInput[26] = writeData;
 | 
			
		||||
			5'b11010 : regInput[27] = writeData;
 | 
			
		||||
			5'b11111 : regInput[28] = writeData;
 | 
			
		||||
			5'b11101 : regInput[29] = writeData;
 | 
			
		||||
			5'b11110 : regInput[30] = writeData;
 | 
			
		||||
			5'b11111 : regInput[31] = writeData;
 | 
			
		||||
			default : regInput[0] = `XLEN'hx;
 | 
			
		||||
		endcase
 | 
			
		||||
	end	
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
endmodule
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user