From: rahulb <rahul bodduna>
Date: Mon, 30 Jul 2018 10:58:36 +0000 (+0530)
Subject: PLIC modified to support interrupts upto 1024
X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=df9621ad270f10a2f59262cb5d6c5898fd50bbf4;p=shakti-peripherals.git

PLIC modified to support interrupts upto 1024
---

diff --git a/src/peripherals/plic/encoder.bsv b/src/peripherals/plic/encoder.bsv
new file mode 100644
index 0000000..4a26491
--- /dev/null
+++ b/src/peripherals/plic/encoder.bsv
@@ -0,0 +1,131 @@
+package encoder;
+
+import Vector ::* ;
+`define INPUT 1024 
+`define OUTPUT 10 
+interface Ifc_encoder#(numeric type irpins);
+	method Bit#(TLog#(irpins)) encode(Bit#(irpins) ip);
+endinterface
+
+module mkencoder(Ifc_encoder#(irpins))
+		provisos(Log#(irpins, irid),
+				 Add#(a__, irpins, `INPUT),
+				 Add#(b__, irid, `OUTPUT));
+	function Bit#(irid) fn_encoder(Bit#(irpins) irp);
+		Bit#(`INPUT) ip = zeroExtend(irp);
+		Bit#(`OUTPUT) result=0;
+		Vector#(TDiv#(`INPUT,2),Bit#(1)) ip1;
+		Vector#(TDiv#(`INPUT,4),Bit#(1)) ip2;
+		Vector#(TDiv#(`INPUT,8),Bit#(1)) ip3;
+		Vector#(TDiv#(`INPUT,16),Bit#(1)) ip4;
+		Vector#(TDiv#(`INPUT,32),Bit#(1)) ip5;
+		Vector#(TDiv#(`INPUT,64),Bit#(1)) ip6;
+		Vector#(TDiv#(`INPUT,128),Bit#(1)) ip7;
+		Vector#(TDiv#(`INPUT,256),Bit#(1)) ip8;
+		Vector#(TDiv#(`INPUT,512),Bit#(1)) ip9;
+		Vector#(TDiv#(`INPUT,2),Bit#(1)) pp1;
+		Vector#(TDiv#(`INPUT,4),Bit#(1)) pp2;
+		Vector#(TDiv#(`INPUT,8),Bit#(1)) pp3;
+		Vector#(TDiv#(`INPUT,16),Bit#(1)) pp4;
+		Vector#(TDiv#(`INPUT,32),Bit#(1)) pp5;
+		Vector#(TDiv#(`INPUT,64),Bit#(1)) pp6;
+		Vector#(TDiv#(`INPUT,128),Bit#(1)) pp7;
+		Vector#(TDiv#(`INPUT,256),Bit#(1)) pp8;
+		Vector#(TDiv#(`INPUT,512),Bit#(1)) pp9;
+		Bit#(1) ip10;
+		Bit#(1) pp10;
+		
+		for(Integer i=0;i<`INPUT/2;i=i+1) begin
+			ip1[i]=ip[i*2+1] | ip[i*2];
+		end
+		for(Integer i=0;i<`INPUT/4;i=i+1) begin
+			ip2[i]=ip1[i*2+1] | ip1[i*2];
+		end
+		for(Integer i=0;i<`INPUT/8;i=i+1) begin
+			ip3[i]=ip2[i*2+1] | ip2[i*2];
+		end
+		for(Integer i=0;i<`INPUT/16;i=i+1) begin
+			ip4[i]=ip3[i*2+1] | ip3[i*2];
+		end
+		for(Integer i=0;i<`INPUT/32;i=i+1) begin
+			ip5[i]=ip4[i*2+1] | ip4[i*2];
+		end
+		for(Integer i=0;i<`INPUT/64;i=i+1) begin
+			ip6[i]=ip5[i*2+1] | ip5[i*2];
+		end
+		for(Integer i=0;i<`INPUT/128;i=i+1) begin
+			ip7[i]=ip6[i*2+1] | ip6[i*2];
+		end
+		for(Integer i=0;i<`INPUT/256;i=i+1) begin
+			ip8[i]=ip7[i*2+1] | ip7[i*2];
+		end
+		for(Integer i=0;i<`INPUT/512;i=i+1) begin
+			ip9[i]=ip8[i*2+1] | ip8[i*2];
+		end
+
+		for(Integer i=0;i<`INPUT/2;i=i+1) begin
+			pp1[i]=ip[i*2+1]==1?1:ip[i*2]==1?0:0;
+		end
+		for(Integer i=0;i<`INPUT/4;i=i+1) begin
+			pp2[i]=ip1[i*2+1]==1?1:ip1[i*2]==1?0:0;
+		end
+		for(Integer i=0;i<`INPUT/8;i=i+1) begin
+			pp3[i]=ip2[i*2+1]==1?1:ip2[i*2]==1?0:0;
+		end
+		for(Integer i=0;i<`INPUT/16;i=i+1) begin
+			pp4[i]=ip3[i*2+1]==1?1:ip3[i*2]==1?0:0;
+		end
+		for(Integer i=0;i<`INPUT/32;i=i+1) begin
+			pp5[i]=ip4[i*2+1]==1?1:ip4[i*2]==1?0:0;
+		end
+		for(Integer i=0;i<`INPUT/64;i=i+1) begin
+			pp6[i]=ip5[i*2+1]==1?1:ip5[i*2]==1?0:0;
+		end
+		for(Integer i=0;i<`INPUT/128;i=i+1) begin
+			pp7[i]=ip6[i*2+1]==1?1:ip6[i*2]==1?0:0;
+		end
+		for(Integer i=0;i<`INPUT/256;i=i+1) begin
+			pp8[i]=ip7[i*2+1]==1?1:ip7[i*2]==1?0:0;
+		end
+		for(Integer i=0;i<`INPUT/512;i=i+1) begin
+			pp9[i]=ip8[i*2+1]==1?1:ip8[i*2]==1?0:0;
+		end
+
+		pp10=ip9[1]==1?1:ip9[0]==1?0:0;
+		ip10=ip9[1] | ip9[0];
+
+		result[0] = pp10;
+		let op9 = pp9[result[1:0]];
+		result = {result[8:0],op9};
+		let op8 = pp8[result[2:0]];
+		result = {result[8:0],op8};
+		let op7 = pp7[result[3:0]];
+		result = {result[8:0],op7};
+		let op6 = pp6[result[4:0]];
+		result = {result[8:0],op6};
+		let op5 = pp5[result[5:0]];
+		result = {result[8:0],op5};
+		let op4 = pp4[result[6:0]];
+		result = {result[8:0],op4};
+		let op3 = pp3[result[7:0]];
+		result = {result[8:0],op3};
+		let op2 = pp2[result[8:0]];
+		result = {result[8:0],op2};
+		let op1 = pp1[result[9:0]];
+		result = {result[8:0],op1};
+		return truncate(result);
+	endfunction
+	
+method Bit#(irid) encode(Bit#(irpins) ip);
+	return fn_encoder(ip);
+endmethod
+endmodule
+
+(*synthesize*)
+module mkSencoder(Ifc_encoder#(512));
+	let ifc();
+	mkencoder inst(ifc);
+	return ifc();
+endmodule
+
+endpackage
diff --git a/src/peripherals/plic/plic.bsv b/src/peripherals/plic/plic.bsv
index 0e94ee7..1f1661a 100644
--- a/src/peripherals/plic/plic.bsv
+++ b/src/peripherals/plic/plic.bsv
@@ -13,14 +13,17 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 */
 package plic;
 	import Vector::*;
-	//import defined_parameters::*;
 	import defined_types::*;
 	import ConfigReg::*;
 	import Semi_FIFOF::*;
 	import AXI4_Lite_Types::*;
 	import BUtils ::*;
 	import ConcatReg ::*;
+	import encoder ::*;
 	`include "instance_defines.bsv"
+
+`define INTERRUPT_LEVELS 8
+
   //	import ConfigReg::*;
 /*Platform level interrupt controller:
 	Refer to RISC-V privilege spec-v-1.10 chapter 7
@@ -51,7 +54,8 @@ package plic;
 */
 
 
-interface Ifc_PLIC#(numeric type addr_width,numeric type word_size,numeric type no_of_ir_pins);
+interface Ifc_PLIC#(numeric type addr_width,numeric type word_size,numeric type no_of_ir_pins,
+																	numeric type no_of_ir_levels);
 	interface Vector#(no_of_ir_pins,Ifc_global_interrupt) ifc_external_irq;
 	interface Ifc_program_registers#(addr_width,word_size) ifc_prog_reg;
 	method ActionValue#(Tuple2#(Bool,Bool)) intrpt_note;
@@ -59,95 +63,36 @@ interface Ifc_PLIC#(numeric type addr_width,numeric type word_size,numeric type
 endinterface
 
 //(*conflict_free = "rl_prioritise, prog_reg"*)
-module mkplic(Ifc_PLIC#(addr_width,word_size,no_of_ir_pins))
+module mkplic(Ifc_PLIC#(addr_width,word_size,no_of_ir_pins,no_of_ir_levels))
 	provisos(
-	Log#(no_of_ir_pins, priority_bits),
+	Log#(no_of_ir_pins, ir_bits),
+	Log#(no_of_ir_levels, priority_bits),
 	Mul#(8,word_size,data_width),
-	Add#(1,priority_bits,x_priority_bits),
-	Add#(msb_priority,1,priority_bits),
-	Add#(msb_priority_bits,1,no_of_ir_pins),
-	Add#(b__, no_of_ir_pins, data_width),
-	Add#(c__, priority_bits, data_width),
-	Add#(a__, 8, no_of_ir_pins),
-	Add#(e__, 32, data_width),
-	Add#(g__, 32, no_of_ir_pins),
-	Add#(f__, 3, priority_bits),
-	Add#(d__, 5, priority_bits)
+	//Mul#(3,no_iterations,ir_bits),
+	Add#(1,ir_bits,x_ir_bits),
+	Add#(msb_ir_bits,1,ir_bits),
+	Add#(msb_ir_pins,1,no_of_ir_pins),
+	Add#(msb_priority_levels,1,no_of_ir_levels),
+	Add#(msb_priority_bits,1,priority_bits),
+	Add#(a__, no_of_ir_levels, data_width),
+	Add#(b__, ir_bits, data_width),
+	Add#(c__, no_of_ir_pins, 1024),
+	Add#(d__, ir_bits, 10),
+	Add#(f__, no_of_ir_levels, 1024),
+	Add#(g__, priority_bits, 10),
+	Add#(h__, no_of_ir_levels, 32),
+	Add#(e__, 32, data_width)
+	//Mul#(no_iterations, 3, ir_bits),
 	);
 	let v_no_of_ir_pins = valueOf(no_of_ir_pins);
-	let v_priority_bits = valueOf(priority_bits);
-	let v_msb_priority_bits = valueOf(msb_priority_bits);
-	let v_msb_priority = valueOf(msb_priority);
+	let v_ir_bits = valueOf(ir_bits);
+	let v_msb_ir_bits = valueOf(msb_ir_bits);
+	let v_msb_ir_pins = valueOf(msb_ir_pins);
+	let v_msb_priority = valueOf(msb_priority_levels);
 	let v_data_width = valueOf(data_width);
 
 	//(* noinline *)
 
-	/* This function defines the working of priority encoder with 4 bit inputs */
-	function Bit#(8) priority_encoder(Bit#(8) inp, Bool alu_free);
-	   Bit#(8) outp = 0;
-	   if(alu_free) begin
-		if(inp[0]==1)
-		   outp[0] = 1'b1;
-		else if(inp[1]==1)
-		   outp[1] = 1'b1;
-		else if(inp[2]==1)
-		   outp[2] = 1'b1;
-		else if(inp[3]==1)
-		   outp[3] = 1'b1;
-		else if(inp[4]==1)
-		   outp[4] = 1'b1;
-		else if(inp[5]==1)
-		   outp[5] = 1'b1;
-		else if(inp[6]==1)
-		   outp[6] = 1'b1;
-		else if(inp[7]==1)
-		   outp[7] = 1'b1;
-	   end
-	
-	   return outp;
-	endfunction
-	
-	function bit any_req(Bit#(8) inp);
-	   return inp[0] | inp[1] | inp[2] | inp[3] | inp[4] | inp[5] | inp[6] | inp[7];
-	endfunction
-	
-	/* Encodes the grant vector */
-	function Bit#(x_priority_bits) encoder(Bit#(no_of_ir_pins) inp);
-	   Bit#(priority_bits) outp = 0;
-	   bit outp_valid = 1'b1;
-	   for(Integer i = 0; i < v_no_of_ir_pins; i = i+1) begin
-			if(inp[i]==1)
-				outp = fromInteger(i);
-	   end
-	   return {outp_valid,outp};
-	endfunction
-	
-  function Reg#(t) readOnlyReg(t r);
-    return (interface Reg;
-       method t _read = r;
-       method Action _write(t x) = noAction;
-    endinterface);
-  endfunction
-
-	/* Request vectors are passed down the tree and the grants are given back */
-	function Bit#(no_of_ir_pins) encoder_tree(Bit#(no_of_ir_pins) inp);
-		Bit#(no_of_ir_pins) outp = 0;
-		//request to root
-		Bit#(8) root_reqs;
-		
-		//grant from root
-		Bit#(8) root_grants;
-		
-		for(Integer i=0;i<8;i=i+1)
-		   root_reqs[i] = any_req(inp[8*fromInteger(i)+7:8*fromInteger(i)]);
-		
-		root_grants = priority_encoder(root_reqs, True);
-		
-		//grants are passed back to leaves
-		for(Integer i=0;i<8;i=i+1)
-			outp[8*fromInteger(i)+7:8*fromInteger(i)] = priority_encoder(inp[8*fromInteger(i)+7:8*fromInteger(i)], unpack(root_grants[i]));
-		return outp;
-	endfunction			
 
 	Vector#(no_of_ir_pins,Array#(Reg#(Bool))) rg_ip <- replicateM(mkCReg(2,False));
 	Reg#(Bool) rg_ie[v_no_of_ir_pins];
@@ -156,57 +101,117 @@ module mkplic(Ifc_PLIC#(addr_width,word_size,no_of_ir_pins))
 			rg_ie[i] = readOnlyReg(True); 
 		else
 			rg_ie[i] <- mkReg(False); 
-	Reg#(Bit#(32)) rg_priority_low[v_no_of_ir_pins];
+	Reg#(Bit#(no_of_ir_levels)) rg_priority_low[v_no_of_ir_pins];
 	for(Integer i =0; i < v_no_of_ir_pins; i=i+1)
 		if(i==28 || i == 29)
-			rg_priority_low[i] = readOnlyReg(32'h00000001);
+			rg_priority_low[i] = readOnlyReg(1);
 		else
 			rg_priority_low[i] <- mkConfigReg(0);
-	Reg#(Bit#(no_of_ir_pins)) rg_priority[v_no_of_ir_pins];
+	Reg#(Bit#(32)) rg_priority[v_no_of_ir_pins];
 	for(Integer i=0;i < v_no_of_ir_pins;i=i+1)
 		rg_priority[i] = concatReg2(readOnlyReg(0), rg_priority_low[i]);
-	Reg#(Bit#(5)) rg_priority_threshold_low <- mkReg(0);
-	Reg#(Bit#(priority_bits))	 rg_priority_threshold = concatReg2(readOnlyReg(0),rg_priority_threshold_low);
-	Reg#(Bit#(priority_bits))	 rg_interrupt_id <- mkConfigReg(0);
+	Reg#(Bit#(no_of_ir_levels))	 rg_priority_threshold <- mkReg(0);
+	Reg#(Bit#(ir_bits))	 rg_interrupt_id <- mkConfigReg(0);
 	Reg#(Bool)	 rg_interrupt_valid <- mkConfigReg(False);
-	Reg#(Maybe#(Bit#(priority_bits))) rg_completion_id <- mkReg(tagged Invalid);
+	Reg#(Maybe#(Bit#(ir_bits))) rg_completion_id <- mkReg(tagged Invalid);
+	Reg#(Bit#(no_of_ir_pins)) rg_total_priority <- mkReg(0);
+	Reg#(Bit#(1)) rg_plic_state <- mkReg(0); //TODO put an enum later
+	Reg#(Bit#(no_of_ir_levels)) rg_winner_priority <- mkReg(0);
+	Ifc_encoder#(no_of_ir_levels) ir_priority_encoder <- mkencoder();
+	Ifc_encoder#(no_of_ir_pins) irencoder <- mkencoder();
 
-	rule rl_prioritise;
+	rule rl_prioritise(rg_plic_state==0);
 		Bit#(priority_bits) winner_priority = 0;
-		Bit#(priority_bits) winner_interrupts = 0;
-		Bit#(x_priority_bits) ir_id_valid = 0;
-		Bit#(no_of_ir_pins) lv_priority = 0;
+		Bit#(ir_bits) winner_interrupts = 0;
+		Bit#(x_ir_bits) ir_id_valid = 0;
+		Bit#(no_of_ir_levels) lv_priority = 0;
 		Bit#(no_of_ir_pins) lv_total_priority = 0;
 		for(Integer i = 0; i < v_no_of_ir_pins; i = i + 1)
 		 begin
 			
 			if(rg_ip[i][1] && rg_ie[i]) begin
-				lv_priority = lv_priority | rg_priority[i];
-				winner_interrupts = fromInteger(i);
+				lv_priority = lv_priority | truncate(rg_priority[i]);
 				`ifdef verbose $display($time,"\tInterrupt id %d and priority is %d", i, lv_priority);`endif
 			end
 		end
-		winner_priority = encoder(encoder_tree(lv_priority))[v_msb_priority:0];
+		winner_priority = ir_priority_encoder.encode(lv_priority);
 		`ifdef verbose $display($time,"\t winner priority is  %d", winner_priority);`endif
 		for(Integer i = 0; i < v_no_of_ir_pins; i = i + 1) begin
 			if(rg_priority[i][winner_priority] == 1 && rg_ip[i][1] && rg_ie[i])
 				lv_total_priority[i] = 1;
 		end
-		if(lv_total_priority!=0)
-		winner_interrupts = encoder(encoder_tree(lv_total_priority))[v_msb_priority:0];
-		if(winner_interrupts!=0) begin
-			ir_id_valid = encoder(rg_priority[winner_interrupts]);
-			if(winner_priority <= rg_priority_threshold)
-			 begin
-				
-				`ifdef verbose $display("Interrupt valid");`endif
-				rg_interrupt_id <= winner_interrupts;
-				rg_interrupt_valid <= True;
-				$display($time,"\t The highest priority interrupt is  %d and the priority is ", winner_interrupts, winner_priority);
-			end
+		if(lv_total_priority!=0) begin
+			rg_total_priority <= lv_total_priority;
+			rg_plic_state <= 1;
+			Bit#(no_of_ir_levels) lv_winner_priority = 0;
+			lv_winner_priority[winner_priority] = 1;
+			rg_winner_priority <= lv_winner_priority;
 		end
 	endrule
 
+	rule rl_encoder(rg_plic_state==1);
+		Bit#(ir_bits) interrupt_id = irencoder.encode(rg_total_priority);
+		if(interrupt_id!=0 && rg_priority_threshold >= rg_winner_priority) begin
+			`ifdef verbose $display("Interrupt valid");`endif
+			rg_interrupt_id <= interrupt_id;
+			rg_interrupt_valid <= True;
+			$display($time,"\t The highest priority interrupt is  %d and the priority is ", interrupt_id, rg_winner_priority);
+		end
+		rg_plic_state <= 0;
+			
+		
+		//if(lv_total_priority!=0)
+		//winner_interrupts = encoder(encoder_tree(lv_total_priority))[v_msb_priority:0];
+		//if(winner_interrupts!=0) begin
+		//	if(winner_priority <= rg_priority_threshold)
+		//	 begin
+		//		
+		//		`ifdef verbose $display("Interrupt valid");`endif
+		//		rg_interrupt_id <= winner_interrupts;
+		//		rg_interrupt_valid <= True;
+		//		$display($time,"\t The highest priority interrupt is  %d and the priority is ", winner_interrupts, winner_priority);
+		//	end
+		//end
+	endrule
+
+
+	//for(Integer i = 0; i<no_iterations; i=i+1) begin
+	//	rule rl_encoder(rg_plic_state==1);
+	//		Bit#(no_of_ir_pins) lv_total_priority = rg_total_priority;
+	//		Vector#(tree_ir, Bit#(8)) lv_priority_ip;
+	//		Bit#(tree_ir) level_encoder;
+	//		Vector#(tree_ir, 3) ir_encoded;
+	//		
+	//		for(Integer i=0;i<tree_ir;i=i+1) begin
+	//			lv_priority_ip[i]=lv_total_priority[i*8+7:i*8];
+	//		end
+	//		for(Integer i=0;i<tree_ir;i=i+1) begin
+	//			level_encoder[i] = any_req(lv_priority_ip[i]);
+	//		end
+	//		for(Integer i=0;i<-tree_ir;i=i+1) begin
+	//			ir_encoded[i] = encoder(priority_encoder(lv_priority_ip));
+	//		end
+	//		for(Integer i=0;i<-tree_ir;i=i+1) begin
+	//			rg_prioritized_encoded <= ir_encoded;
+	//		end
+	//			
+	//		
+	//		//if(lv_total_priority!=0)
+	//		//winner_interrupts = encoder(encoder_tree(lv_total_priority))[v_msb_priority:0];
+	//		//if(winner_interrupts!=0) begin
+	//		//	ir_id_valid = encoder(rg_priority[winner_interrupts]);
+	//		//	if(winner_priority <= rg_priority_threshold)
+	//		//	 begin
+	//		//		
+	//		//		`ifdef verbose $display("Interrupt valid");`endif
+	//		//		rg_interrupt_id <= winner_interrupts;
+	//		//		rg_interrupt_valid <= True;
+	//		//		$display($time,"\t The highest priority interrupt is  %d and the priority is ", winner_interrupts, winner_priority);
+	//		//	end
+	//		//end
+	//	endrule
+	//end
+
 	Vector#(no_of_ir_pins, Ifc_global_interrupt) temp_ifc_irq;
 
 	for(Integer i = 0; i < v_no_of_ir_pins; i = i + 1) begin
@@ -229,38 +234,36 @@ interface ifc_prog_reg = interface Ifc_program_registers;
 								//update memory mapped registers
 								`ifdef verbose $display($time,"\tPLIC : programming registers for address %h", mem_req.address);`endif
 								let address = mem_req.address;
-								Bit#(priority_bits) source_id=0;
+								Bit#(ir_bits) source_id=0;
 								Bit#(data_width) data_return = 0;
-//								if(address < 'h0C001000) begin
-								if (address < `PLICBase + 'h1000)begin
+								if(address < 'h0C001000) begin
 									address = address >> 2;
 									if(mem_req.ld_st == Load) begin
-										source_id = address[v_msb_priority:0];
+										source_id = address[v_msb_ir_bits:0];
 										`ifdef verbose $display($time,"\tPLIC : source %d Priority set to %h", source_id, mem_req.write_data);`endif
 										data_return = zeroExtend(rg_priority[source_id]);
 									end
 									else if(mem_req.ld_st == Store) begin
-										Bit#(no_of_ir_pins) store_data;
+										Bit#(data_width) store_data;
 										if(mem_req.byte_offset==0)
-											store_data=mem_req.write_data[v_msb_priority_bits:0];
+											store_data=mem_req.write_data[v_msb_ir_pins:0];
 										else
 											store_data=mem_req.write_data[v_data_width-1:v_data_width-v_no_of_ir_pins];
 										mem_req.byte_offset = mem_req.byte_offset >> 2;
-										source_id = address[v_msb_priority:0] | zeroExtend(mem_req.byte_offset);
+										source_id = address[v_msb_ir_bits:0];
 										$display($time,"\tPLIC : source %d Priority set to %h", source_id, store_data);
-										rg_priority[source_id] <= store_data;
+										rg_priority[source_id] <= truncate(store_data);
 									end
 								end
-								//else if(address < 'h0C002000) begin
-								  else if(address<`PLICBase+'h2000)begin
+								else if(address < 'h0C002000) begin
 									if(mem_req.ld_st == Load) begin
-										source_id = address[v_msb_priority:0];
+										source_id = address[v_msb_ir_bits:0];
 										source_id = source_id << 3;
 										for(Integer i = 0; i < 8; i = i+1)
 											data_return[i] = pack(rg_ip[source_id + fromInteger(i)][1]);
 									end
 									else if(mem_req.ld_st == Store) begin
-										source_id = zeroExtend(mem_req.byte_offset);
+										source_id = address[v_msb_ir_bits:0];
 										source_id = source_id << 3;
 										for(Integer i = 0; i < 8; i = i+1) begin
 											`ifdef verbose $display($time,"\tPLIC : pending interrupt  %b id %d", mem_req.write_data[i], source_id);`endif
@@ -268,17 +271,16 @@ interface ifc_prog_reg = interface Ifc_program_registers;
 										end
 									end
 								end
-								//else if(address < 'h0C020000) begin
-								  else if(address < `PLICBase+'h20000)begin
+								else if(address < 'h0C020000) begin
 									if(mem_req.ld_st == Load) begin
-										source_id = address[v_msb_priority:0];
+										source_id = address[v_msb_ir_bits:0];
 										source_id = source_id << 3;
 										for(Integer i = 0; i < 8; i = i+1)
 											data_return[i] = pack(rg_ie[source_id + fromInteger(i)]);
                                             `ifdef verbose $display($time,"PLIC: Printing Source Enable Interrupt: %h data_return: %h",source_id,data_return); `endif
 									end
 									else if(mem_req.ld_st == Store) begin
-										source_id = zeroExtend(mem_req.byte_offset);
+										source_id = address[v_msb_ir_bits:0];
 										source_id = source_id << 3;
 										for(Integer i = 0; i < 8; i = i+1) begin
 											`ifdef verbose $display($time,"\tPLIC : enabled interrupt  %b id %d", mem_req.write_data[i], source_id);`endif
@@ -286,23 +288,21 @@ interface ifc_prog_reg = interface Ifc_program_registers;
 										end
 									end
 								end
-						//		else if(address == 'hC200000) begin
-								else if(address ==`PLICBase+'h200000)begin
+								else if(address == 'hC200000) begin
 									if(mem_req.ld_st == Load) begin
 										data_return = zeroExtend(rg_priority_threshold); 
 									end
 									else if(mem_req.ld_st == Store)
 										rg_priority_threshold <= mem_req.write_data[v_msb_priority:0];
 								end
-		 				//		else if(address == 'hC200004) begin
-								else if(address == `PLICBase+'h200004)begin
+								else if(address == 'hC200004) begin
 									if(mem_req.ld_st == Load) begin
 										data_return = zeroExtend(rg_interrupt_id); 
 										rg_ip[rg_interrupt_id][1] <= False;
                                        `ifdef verbose $display($time,"rg_ip is made false here"); `endif
 									end
 									else if(mem_req.ld_st == Store) begin
-										source_id = mem_req.write_data[v_msb_priority:0];
+										source_id = mem_req.write_data[v_msb_ir_bits:0];
 										rg_completion_id <= tagged Valid source_id;
                                         `ifdef verbose $display("rg_completion_id is made tagged valid and completion is signaled-- source_id: %d",source_id); `endif
 									end
@@ -339,7 +339,7 @@ endinterface
 module mkplicperipheral(Ifc_PLIC_AXI);
 
 AXI4_Lite_Slave_Xactor_IFC #(`PADDR, `Reg_width, `USERSPACE)  s_xactor_plic <- mkAXI4_Lite_Slave_Xactor;
-Ifc_PLIC#(`PADDR, `DCACHE_WORD_SIZE, `INTERRUPT_PINS) plic <- mkplic();
+Ifc_PLIC#(`PADDR, `DCACHE_WORD_SIZE, `INTERRUPT_PINS, `INTERRUPT_LEVELS) plic <- mkplic();
 
 (*preempts="rl_config_plic_reg_read, rl_config_plic_reg_write"*)
 	rule rl_config_plic_reg_write;
@@ -362,11 +362,12 @@ Ifc_PLIC#(`PADDR, `DCACHE_WORD_SIZE, `INTERRUPT_PINS) plic <- mkplic();
 		let ar <- pop_o(s_xactor_plic.o_rd_addr);
 		let x <- plic.ifc_prog_reg.prog_reg(UncachedMemReq{address : ar.araddr, transfer_size : 'd3, 
 	    																				u_signed : 0, byte_offset : 0, ld_st : Load}); 
-//        if(ar.arsize==3'd0)
-//            x = duplicate(x[7:0]);
-//        else if(ar.arsize==3'd1)
-//            x = duplicate(x[15:0]);
-//        else if(ar.arsize==3'd2)
+        if(ar.arsize==3'd0)
+            x = duplicate(x[7:0]);
+        else if(ar.arsize==3'd1)
+            x = duplicate(x[15:0]);
+        else if(ar.arsize==3'd2)
+            x = duplicate(x[7:0]);
 
 		let r = AXI4_Lite_Rd_Data {rresp: AXI4_LITE_OKAY, rdata: duplicate(x), ruser: 0};
 		s_xactor_plic.i_rd_data.enq(r);