initial commit of rocket chisel project, riscv assembly tests and benchmarks
This commit is contained in:
		
							
								
								
									
										74
									
								
								rocket/src/main/scala/arbiter.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								rocket/src/main/scala/arbiter.scala
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,74 @@
 | 
				
			|||||||
 | 
					package Top {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import Chisel._;
 | 
				
			||||||
 | 
					import Node._;
 | 
				
			||||||
 | 
					import Constants._;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ioMem() extends Bundle
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  val req_val = Bool('output);
 | 
				
			||||||
 | 
					  val req_rdy = Bool('input);
 | 
				
			||||||
 | 
					  val req_rw  = Bool('output);
 | 
				
			||||||
 | 
					  val req_addr = UFix(32, 'output);
 | 
				
			||||||
 | 
					  val req_wdata = Bits(128, 'output);
 | 
				
			||||||
 | 
					  val req_tag = Bits(4, 'output);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  val resp_val = Bool('input);
 | 
				
			||||||
 | 
					  val resp_tag = Bits(4, 'input);
 | 
				
			||||||
 | 
					  val resp_data = Bits(128, 'input);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ioArbiter extends Bundle() {
 | 
				
			||||||
 | 
					  val mem = new ioMem();
 | 
				
			||||||
 | 
					  val dcache = new ioDcache();
 | 
				
			||||||
 | 
					//   val icache = new ioIcache();
 | 
				
			||||||
 | 
					  val icache = new ioIPrefetcherMem().flip();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class rocketMemArbiter extends Component {
 | 
				
			||||||
 | 
					  val io = new ioArbiter();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // *****************************
 | 
				
			||||||
 | 
					  // Interface to memory
 | 
				
			||||||
 | 
					  // *****************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Memory request is valid if either icache or dcache have a valid request
 | 
				
			||||||
 | 
					  io.mem.req_val := (io.icache.req_val || io.dcache.req_val);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Set read/write bit.  Icache always reads
 | 
				
			||||||
 | 
					  io.mem.req_rw := Mux(io.icache.req_val,Bool(false),io.dcache.req_rw);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Give priority to Icache
 | 
				
			||||||
 | 
					  io.mem.req_addr := Mux(io.icache.req_val,io.icache.req_addr,io.dcache.req_addr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // high bit of tag=0 for I$, tag=0 for D$
 | 
				
			||||||
 | 
					//   io.mem.req_tag := Mux(io.icache.req_val,Bits(0,4),Bits(1,4));
 | 
				
			||||||
 | 
					  io.mem.req_tag := Mux(io.icache.req_val, 
 | 
				
			||||||
 | 
					                        Cat(Bits(0,1), io.icache.req_tag),
 | 
				
			||||||
 | 
					                        Cat(Bits(1,1), io.dcache.req_tag));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Just pass through write data (only D$ will write)
 | 
				
			||||||
 | 
					  io.mem.req_wdata := io.dcache.req_wdata;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // *****************************
 | 
				
			||||||
 | 
					  // Interface to caches
 | 
				
			||||||
 | 
					  // *****************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Read for request from cache if the memory is ready.  Give priority to I$
 | 
				
			||||||
 | 
					  io.icache.req_rdy := io.mem.req_rdy;
 | 
				
			||||||
 | 
					  io.dcache.req_rdy := io.mem.req_rdy && !io.icache.req_val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Response will only be valid for D$ or I$ not both because of tag bits
 | 
				
			||||||
 | 
					  io.icache.resp_val := io.mem.resp_val && !io.mem.resp_tag(3).toBool;
 | 
				
			||||||
 | 
					  io.dcache.resp_val := io.mem.resp_val &&  io.mem.resp_tag(3).toBool;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Feed through data to both 
 | 
				
			||||||
 | 
					  io.icache.resp_data := io.mem.resp_data;
 | 
				
			||||||
 | 
					  io.dcache.resp_data := io.mem.resp_data;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  io.icache.resp_tag := io.mem.resp_tag(2,0);
 | 
				
			||||||
 | 
					  io.dcache.resp_tag := io.mem.resp_tag(2,0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										153
									
								
								rocket/src/main/scala/consts.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										153
									
								
								rocket/src/main/scala/consts.scala
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,153 @@
 | 
				
			|||||||
 | 
					package Top {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import Chisel._
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					object Constants
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  val BR_N    = UFix(0, 4);
 | 
				
			||||||
 | 
					  val BR_EQ   = UFix(1, 4);
 | 
				
			||||||
 | 
					  val BR_NE   = UFix(2, 4);
 | 
				
			||||||
 | 
					  val BR_LT   = UFix(3, 4);
 | 
				
			||||||
 | 
					  val BR_LTU  = UFix(4, 4);
 | 
				
			||||||
 | 
					  val BR_GE   = UFix(5, 4);
 | 
				
			||||||
 | 
					  val BR_GEU  = UFix(6, 4);
 | 
				
			||||||
 | 
					  val BR_J    = UFix(7, 4);
 | 
				
			||||||
 | 
					  val BR_JR   = UFix(8, 4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val PC_4   = UFix(0, 3);
 | 
				
			||||||
 | 
					  val PC_BTB = UFix(1, 3);
 | 
				
			||||||
 | 
					  val PC_EX4 = UFix(2, 3);
 | 
				
			||||||
 | 
					  val PC_BR  = UFix(3, 3);
 | 
				
			||||||
 | 
					  val PC_J   = UFix(4, 3);
 | 
				
			||||||
 | 
					  val PC_JR  = UFix(5, 3);
 | 
				
			||||||
 | 
					  val PC_PCR = UFix(6, 3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val KF_Y  = UFix(1, 1);
 | 
				
			||||||
 | 
					  val KF_N  = UFix(0, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val REN_Y = UFix(1, 1);
 | 
				
			||||||
 | 
					  val REN_N = UFix(0, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val AS_X    = UFix(0, 1);
 | 
				
			||||||
 | 
					  val AS_IMM  = UFix(0, 1);
 | 
				
			||||||
 | 
					  val AS_RS2  = UFix(1, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val A2_X     = UFix(0, 2);
 | 
				
			||||||
 | 
					  val A2_0     = UFix(0, 2);
 | 
				
			||||||
 | 
					  val A2_SEXT  = UFix(1, 2);
 | 
				
			||||||
 | 
					  val A2_RS2   = UFix(2, 2);
 | 
				
			||||||
 | 
					  val A2_SPLIT = UFix(3, 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val A1_X    = UFix(0, 1);
 | 
				
			||||||
 | 
					  val A1_RS1  = UFix(0, 1);
 | 
				
			||||||
 | 
					  val A1_LUI  = UFix(1, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val MUL_X     = UFix(0, 3);
 | 
				
			||||||
 | 
					  val MUL_NO    = UFix(0, 3);
 | 
				
			||||||
 | 
					  val MUL_64    = UFix(1, 3);
 | 
				
			||||||
 | 
					  val MUL_64H   = UFix(2, 3);
 | 
				
			||||||
 | 
					  val MUL_64HU  = UFix(3, 3);
 | 
				
			||||||
 | 
					  val MUL_64HSU = UFix(4, 3);
 | 
				
			||||||
 | 
					  val MUL_32    = UFix(5, 3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val DIV_X    = UFix(0, 4);
 | 
				
			||||||
 | 
					  val DIV_NO   = UFix(0, 4);
 | 
				
			||||||
 | 
					  val DIV_64D  = UFix(1, 4);
 | 
				
			||||||
 | 
					  val DIV_64DU = UFix(2, 4);
 | 
				
			||||||
 | 
					  val DIV_64R  = UFix(3, 4);
 | 
				
			||||||
 | 
					  val DIV_64RU = UFix(4, 4);
 | 
				
			||||||
 | 
					  val DIV_32D  = UFix(5, 4);
 | 
				
			||||||
 | 
					  val DIV_32DU = UFix(6, 4);
 | 
				
			||||||
 | 
					  val DIV_32R  = UFix(7, 4);
 | 
				
			||||||
 | 
					  val DIV_32RU = UFix(8, 4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val M_N = UFix(0, 1);
 | 
				
			||||||
 | 
					  val M_Y = UFix(1, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val WEN_N = UFix(0, 1);
 | 
				
			||||||
 | 
					  val WEN_Y = UFix(1, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val WA_X  = UFix(0, 1);
 | 
				
			||||||
 | 
					  val WA_RD = UFix(0, 1);
 | 
				
			||||||
 | 
					  val WA_RA = UFix(1, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val WB_X   = UFix(0, 3);
 | 
				
			||||||
 | 
					  val WB_PC  = UFix(0, 3);
 | 
				
			||||||
 | 
					  val WB_ALU = UFix(1, 3);
 | 
				
			||||||
 | 
					  val WB_PCR = UFix(2, 3);
 | 
				
			||||||
 | 
					  val WB_CR  = UFix(3, 3);
 | 
				
			||||||
 | 
					  val WB_MUL = UFix(4, 3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val N = UFix(0, 1);
 | 
				
			||||||
 | 
					  val Y = UFix(1, 1);
 | 
				
			||||||
 | 
					  val Y_SH = UFix(1, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//  val FPU_N = UFix(0, 1);
 | 
				
			||||||
 | 
					//  val FPU_Y = FPU_N;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val FWBQ_N = UFix(0, 1);
 | 
				
			||||||
 | 
					  val FWBQ_Y = UFix(1, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val FSDQ_N = UFix(0, 1);
 | 
				
			||||||
 | 
					  val FSDQ_Y = UFix(1, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val FN_X     = UFix(0, 4);
 | 
				
			||||||
 | 
					  val FN_ADD   = UFix(0, 4);
 | 
				
			||||||
 | 
					  val FN_SUB   = UFix(1, 4);
 | 
				
			||||||
 | 
					  val FN_SLT   = UFix(2, 4);
 | 
				
			||||||
 | 
					  val FN_SLTU  = UFix(3, 4);
 | 
				
			||||||
 | 
					  val FN_AND   = UFix(4, 4);
 | 
				
			||||||
 | 
					  val FN_OR    = UFix(5, 4);
 | 
				
			||||||
 | 
					  val FN_XOR   = UFix(6, 4);
 | 
				
			||||||
 | 
					  val FN_SL    = UFix(7, 4);
 | 
				
			||||||
 | 
					  val FN_SR    = UFix(8, 4);
 | 
				
			||||||
 | 
					  val FN_SRA   = UFix(9, 4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val DW_X  = UFix(0, 1);
 | 
				
			||||||
 | 
					  val DW_32 = UFix(0, 1);
 | 
				
			||||||
 | 
					  val DW_64 = UFix(1, 1);
 | 
				
			||||||
 | 
					  val DW_XPR = UFix(1, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val RA = UFix(1, 5);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val MT_X  = Bits("b000", 3);
 | 
				
			||||||
 | 
					  val MT_B  = Bits("b000", 3);
 | 
				
			||||||
 | 
					  val MT_H  = Bits("b001", 3);
 | 
				
			||||||
 | 
					  val MT_W  = Bits("b010", 3);
 | 
				
			||||||
 | 
					  val MT_D  = Bits("b011", 3);
 | 
				
			||||||
 | 
					  val MT_BU = Bits("b100", 3);
 | 
				
			||||||
 | 
					  val MT_HU = Bits("b101", 3);
 | 
				
			||||||
 | 
					  val MT_WU = Bits("b110", 3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val M_X       = UFix(0, 4);
 | 
				
			||||||
 | 
					  val M_XRD     = Bits("b0000", 4); // int load
 | 
				
			||||||
 | 
					  val M_XWR     = Bits("b0001", 4); // int store
 | 
				
			||||||
 | 
					  val M_FRD     = Bits("b0010", 4); // fp load
 | 
				
			||||||
 | 
					  val M_FWR     = Bits("b0011", 4); // fp store
 | 
				
			||||||
 | 
					  val M_FLA     = Bits("b0100", 4); // flush cache
 | 
				
			||||||
 | 
					  val M_XA_ADD  = Bits("b1000", 4);
 | 
				
			||||||
 | 
					  val M_XA_SWAP = Bits("b1001", 4);
 | 
				
			||||||
 | 
					  val M_XA_AND  = Bits("b1010", 4);
 | 
				
			||||||
 | 
					  val M_XA_OR   = Bits("b1011", 4);
 | 
				
			||||||
 | 
					  val M_XA_MIN  = Bits("b1100", 4);
 | 
				
			||||||
 | 
					  val M_XA_MAX  = Bits("b1101", 4);
 | 
				
			||||||
 | 
					  val M_XA_MINU = Bits("b1110", 4);
 | 
				
			||||||
 | 
					  val M_XA_MAXU = Bits("b1111", 4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val PCR_STATUS   = UFix( 0, 5);
 | 
				
			||||||
 | 
					  val PCR_EPC      = UFix( 1, 5);
 | 
				
			||||||
 | 
					  val PCR_BADVADDR = UFix( 2, 5);
 | 
				
			||||||
 | 
					  val PCR_EVEC     = UFix( 3, 5);
 | 
				
			||||||
 | 
					  val PCR_COUNT    = UFix( 4, 5);
 | 
				
			||||||
 | 
					  val PCR_COMPARE  = UFix( 5, 5);
 | 
				
			||||||
 | 
					  val PCR_CAUSE    = UFix( 6, 5);
 | 
				
			||||||
 | 
					  val PCR_MEMSIZE  = UFix( 8, 5);
 | 
				
			||||||
 | 
					  val PCR_LOG      = UFix(10, 5);
 | 
				
			||||||
 | 
					  val PCR_TOHOST   = UFix(16, 5);
 | 
				
			||||||
 | 
					  val PCR_FROMHOST = UFix(17, 5);
 | 
				
			||||||
 | 
					  val PCR_CONSOLE  = UFix(18, 5);
 | 
				
			||||||
 | 
					  val PCR_K0       = UFix(24, 5);
 | 
				
			||||||
 | 
					  val PCR_K1       = UFix(25, 5);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										95
									
								
								rocket/src/main/scala/cpu.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								rocket/src/main/scala/cpu.scala
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,95 @@
 | 
				
			|||||||
 | 
					package Top {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import Chisel._
 | 
				
			||||||
 | 
					import Node._;
 | 
				
			||||||
 | 
					import Constants._;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ioDebug extends Bundle()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  val error_mode  = Bool('output);
 | 
				
			||||||
 | 
					  val log_control = Bool('output);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ioHost(view: List[String] = null) extends Bundle(view)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  val start      = Bool('input);
 | 
				
			||||||
 | 
					  val from_wen   = Bool('input);
 | 
				
			||||||
 | 
					  val from       = Bits(32, 'input);
 | 
				
			||||||
 | 
					  val to         = Bits(32, 'output);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ioConsole(view: List[String] = null) extends Bundle(view)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  val rdy   = Bool('input);
 | 
				
			||||||
 | 
					  val valid = Bool('output);
 | 
				
			||||||
 | 
					  val bits  = Bits(8, 'output);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ioRocket extends Bundle()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  val debug   = new ioDebug();
 | 
				
			||||||
 | 
					  val console = new ioConsole();
 | 
				
			||||||
 | 
					  val host    = new ioHost();
 | 
				
			||||||
 | 
					  val imem    = new ioImem().flip();
 | 
				
			||||||
 | 
					  val dmem    = new ioDmem().flip();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class rocketProc extends Component
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  val io    = new ioRocket();
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  val ctrl  = new rocketCtrl();      
 | 
				
			||||||
 | 
					  val dpath = new rocketDpath();     
 | 
				
			||||||
 | 
					  val mem   = new rocketMemory();    
 | 
				
			||||||
 | 
					  val wb    = new rocketWriteback(); 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  dpath.io.host             ^^ io.host;
 | 
				
			||||||
 | 
					  dpath.io.debug            ^^ io.debug;
 | 
				
			||||||
 | 
					  // dpath.io.wb            <> wb.io;
 | 
				
			||||||
 | 
					  dpath.io.wb.wen           <> wb.io.wb_wen;
 | 
				
			||||||
 | 
					  dpath.io.wb.waddr         <> wb.io.wb_waddr;
 | 
				
			||||||
 | 
					  dpath.io.wb.wdata         <> wb.io.wb_wdata;
 | 
				
			||||||
 | 
					  dpath.io.imem.req_addr    ^^ io.imem.req_addr;
 | 
				
			||||||
 | 
					  dpath.io.imem.resp_data   ^^ io.imem.resp_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ctrl.io.ctrl              <> dpath.io.ctrl;
 | 
				
			||||||
 | 
					  ctrl.io.dpath             <> dpath.io.dpath;
 | 
				
			||||||
 | 
					  // ctrl.io.mem               <> mem.io;
 | 
				
			||||||
 | 
					  ctrl.io.mem.mrq_val       <> mem.io.mem_mrq_val;
 | 
				
			||||||
 | 
					  ctrl.io.mem.mrq_cmd       <> mem.io.mem_mrq_cmd;
 | 
				
			||||||
 | 
					  ctrl.io.mem.mrq_type      <> mem.io.mem_mrq_type;
 | 
				
			||||||
 | 
					  ctrl.io.mem.mrq_deq       <> mem.io.mem_mrq_deq;
 | 
				
			||||||
 | 
					  ctrl.io.mem.xsdq_rdy      <> mem.io.mem_xsdq_rdy;
 | 
				
			||||||
 | 
					  ctrl.io.mem.xsdq_val      <> mem.io.mem_xsdq_val;
 | 
				
			||||||
 | 
					  ctrl.io.mem.dc_busy       := !io.dmem.req_rdy;
 | 
				
			||||||
 | 
					  ctrl.io.host.start        ^^ io.host.start;
 | 
				
			||||||
 | 
					  ctrl.io.imem              ^^ io.imem;
 | 
				
			||||||
 | 
					//   ctrl.io.console           ^^ io.console;
 | 
				
			||||||
 | 
					  ctrl.io.wb.waddr          <> wb.io.wb_waddr;
 | 
				
			||||||
 | 
					  ctrl.io.wb.wen            <> wb.io.wb_wen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // TODO: SHOULD BE THE FOLLOWING BUT NEED BETTER INTERFACE CHUNKS
 | 
				
			||||||
 | 
					  // mem.io.dmem               >< io.dmem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mem.io.dmem_req_val       ^^ io.dmem.req_val;
 | 
				
			||||||
 | 
					  mem.io.dmem_req_rdy       ^^ io.dmem.req_rdy;
 | 
				
			||||||
 | 
					  mem.io.dmem_req_op        ^^ io.dmem.req_op;
 | 
				
			||||||
 | 
					  mem.io.dmem_req_addr      ^^ io.dmem.req_addr;
 | 
				
			||||||
 | 
					  mem.io.dmem_req_data      ^^ io.dmem.req_data;
 | 
				
			||||||
 | 
					  mem.io.dmem_req_wmask     ^^ io.dmem.req_wmask;
 | 
				
			||||||
 | 
					  mem.io.dmem_req_tag       ^^ io.dmem.req_tag;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mem.io.dpath_rs2          <> dpath.io.dpath.rs2;
 | 
				
			||||||
 | 
					  mem.io.dpath_waddr        <> dpath.io.dpath.waddr;
 | 
				
			||||||
 | 
					  mem.io.dpath_alu_out      <> dpath.io.dpath.alu_out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  wb.io.dmem_resp_val       ^^ io.dmem.resp_val;
 | 
				
			||||||
 | 
					  wb.io.dmem_resp_data      ^^ io.dmem.resp_data;
 | 
				
			||||||
 | 
					  wb.io.dmem_resp_tag       ^^ io.dmem.resp_tag;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  io.console.bits     := dpath.io.dpath.rs1(7,0);
 | 
				
			||||||
 | 
					  io.console.valid    := ctrl.io.console.valid;
 | 
				
			||||||
 | 
					  ctrl.io.console.rdy := io.console.rdy;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										405
									
								
								rocket/src/main/scala/ctrl.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										405
									
								
								rocket/src/main/scala/ctrl.scala
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,405 @@
 | 
				
			|||||||
 | 
					package Top {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import Chisel._
 | 
				
			||||||
 | 
					import Node._;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import Constants._
 | 
				
			||||||
 | 
					import Instructions._
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ioCtrl extends Bundle()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  val sel_pc   = UFix(3, 'output);
 | 
				
			||||||
 | 
					  val wen_btb  = Bool('output);
 | 
				
			||||||
 | 
					  val stallf   = Bool('output);
 | 
				
			||||||
 | 
					  val stalld   = Bool('output);
 | 
				
			||||||
 | 
					  val killf    = Bool('output);
 | 
				
			||||||
 | 
					  val killd    = Bool('output);
 | 
				
			||||||
 | 
					  val ren2     = Bool('output);
 | 
				
			||||||
 | 
					  val ren1     = Bool('output);
 | 
				
			||||||
 | 
					  val sel_alu2 = UFix(2, 'output);
 | 
				
			||||||
 | 
					  val sel_alu1 = Bool('output);
 | 
				
			||||||
 | 
					  val fn_dw    = Bool('output);
 | 
				
			||||||
 | 
					  val fn_alu   = UFix(4, 'output);
 | 
				
			||||||
 | 
					  val mul_val  = Bool('output);
 | 
				
			||||||
 | 
					  val mul_fn   = UFix(3, 'output);
 | 
				
			||||||
 | 
					  val mul_wb   = Bool('output);
 | 
				
			||||||
 | 
					  val div_val  = Bool('output);
 | 
				
			||||||
 | 
					  val div_fn   = UFix(4, 'output);
 | 
				
			||||||
 | 
					  val div_wb   = Bool('output);
 | 
				
			||||||
 | 
					  val wen      = Bool('output);
 | 
				
			||||||
 | 
					  val sel_wa   = Bool('output);
 | 
				
			||||||
 | 
					  val sel_wb   = UFix(3, 'output);
 | 
				
			||||||
 | 
					  val ren_pcr  = Bool('output);
 | 
				
			||||||
 | 
					  val wen_pcr  = Bool('output);
 | 
				
			||||||
 | 
					  val xcpt_illegal = Bool('output);
 | 
				
			||||||
 | 
					  val xcpt_privileged = Bool('output);
 | 
				
			||||||
 | 
					  val xcpt_fpu = Bool('output);
 | 
				
			||||||
 | 
					  val xcpt_syscall = Bool('output);
 | 
				
			||||||
 | 
					  val eret    = Bool('output);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ioCtrlDpath extends Bundle()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  val btb_hit = Bool('input);
 | 
				
			||||||
 | 
					  val inst    = UFix(32, 'input);
 | 
				
			||||||
 | 
					  val br_eq   = Bool('input);
 | 
				
			||||||
 | 
					  val br_lt   = Bool('input);
 | 
				
			||||||
 | 
					  val br_ltu  = Bool('input);
 | 
				
			||||||
 | 
					  val div_rdy = Bool('input);
 | 
				
			||||||
 | 
					  val div_result_val = Bool('input);
 | 
				
			||||||
 | 
					  val mul_result_val = Bool('input);
 | 
				
			||||||
 | 
					  val wen     = Bool('input);
 | 
				
			||||||
 | 
					  val waddr   = UFix(5, 'input);
 | 
				
			||||||
 | 
					  val exception = Bool('input);
 | 
				
			||||||
 | 
					  val status  = Bits(8, 'input);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ioCtrlMem extends Bundle()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  val mrq_val  = Bool('output);
 | 
				
			||||||
 | 
					  val mrq_cmd  = UFix(4, 'output);
 | 
				
			||||||
 | 
					  val mrq_type = UFix(3, 'output);
 | 
				
			||||||
 | 
					  val mrq_deq  = Bool('input);
 | 
				
			||||||
 | 
					  val xsdq_rdy = Bool('input);
 | 
				
			||||||
 | 
					  val xsdq_val = Bool('output);
 | 
				
			||||||
 | 
					  val dc_busy  = Bool('input);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ioCtrlImem extends Bundle()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  val req_val  = Bool('output);
 | 
				
			||||||
 | 
					  val req_rdy  = Bool('input);
 | 
				
			||||||
 | 
					  val resp_val = Bool('input);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ioCtrlWB extends Bundle()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  val waddr     = UFix(5, 'input);
 | 
				
			||||||
 | 
					  val wen       = Bool('input);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ioCtrlAll extends Bundle()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  val ctrl    = new ioCtrl();
 | 
				
			||||||
 | 
					  val console = new ioConsole(List("rdy", "valid"));
 | 
				
			||||||
 | 
					  val dpath   = new ioCtrlDpath();
 | 
				
			||||||
 | 
					  val imem    = new ioCtrlImem();
 | 
				
			||||||
 | 
					  val mem     = new ioCtrlMem();
 | 
				
			||||||
 | 
					  val wb      = new ioCtrlWB();
 | 
				
			||||||
 | 
					  val host    = new ioHost(List("start"));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class rocketCtrl extends Component
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  val io = new ioCtrlAll();
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  val xpr64 = Y;
 | 
				
			||||||
 | 
					  val cs =   
 | 
				
			||||||
 | 
					  ListLookup(io.dpath.inst,
 | 
				
			||||||
 | 
					     List(            N,     BR_N,  REN_N,REN_N,A2_X,    A1_X,  DW_X,  FN_X,   M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_N,WA_X, WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					     Array(
 | 
				
			||||||
 | 
					      BNE->      List(Y,     BR_NE, REN_Y,REN_Y,A2_RS2,  A1_RS1,DW_X,  FN_X,   M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_N,WA_X, WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      ADDI->     List(Y,     BR_N,  REN_N,REN_Y,A2_SEXT, A1_RS1,DW_XPR,FN_ADD, M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_Y,WA_RD,WB_ALU,REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      BEQ->      List(Y,     BR_EQ, REN_Y,REN_Y,A2_RS2,  A1_RS1,DW_X,  FN_X,   M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_N,WA_X, WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      BLT->      List(Y,     BR_LT, REN_Y,REN_Y,A2_RS2,  A1_RS1,DW_X,  FN_X,   M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_N,WA_X, WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      BLTU->     List(Y,     BR_LTU,REN_Y,REN_Y,A2_RS2,  A1_RS1,DW_X,  FN_X,   M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_N,WA_X, WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      BGE->      List(Y,     BR_GE, REN_Y,REN_Y,A2_RS2,  A1_RS1,DW_X,  FN_X,   M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_N,WA_X, WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      BGEU->     List(Y,     BR_GEU,REN_Y,REN_Y,A2_RS2,  A1_RS1,DW_X,  FN_X,   M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_N,WA_X, WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      J->        List(Y,     BR_J,  REN_N,REN_N,A2_X,    A1_X,  DW_X,  FN_X,   M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_N,WA_X, WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      JAL->      List(Y,     BR_J,  REN_N,REN_N,A2_X,    A1_X,  DW_X,  FN_X,   M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_Y,WA_RA,WB_PC, REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      JALR_C->   List(Y,     BR_JR, REN_N,REN_Y,A2_SEXT, A1_RS1,DW_XPR,FN_ADD, M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_Y,WA_RD,WB_PC, REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      JALR_J->   List(Y,     BR_JR, REN_N,REN_Y,A2_SEXT, A1_RS1,DW_XPR,FN_ADD, M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_Y,WA_RD,WB_PC, REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      JALR_R->   List(Y,     BR_JR, REN_N,REN_Y,A2_SEXT, A1_RS1,DW_XPR,FN_ADD, M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_Y,WA_RD,WB_PC, REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      LB->       List(Y,     BR_N,  REN_N,REN_Y,A2_SEXT, A1_RS1,DW_XPR,FN_ADD, M_Y,M_XRD,    MT_B, N,MUL_X,     N,DIV_X,    WEN_N,WA_RD,WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      LH->       List(Y,     BR_N,  REN_N,REN_Y,A2_SEXT, A1_RS1,DW_XPR,FN_ADD, M_Y,M_XRD,    MT_H, N,MUL_X,     N,DIV_X,    WEN_N,WA_RD,WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      LW->       List(Y,     BR_N,  REN_N,REN_Y,A2_SEXT, A1_RS1,DW_XPR,FN_ADD, M_Y,M_XRD,    MT_W, N,MUL_X,     N,DIV_X,    WEN_N,WA_RD,WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      LD->       List(xpr64, BR_N,  REN_N,REN_Y,A2_SEXT, A1_RS1,DW_XPR,FN_ADD, M_Y,M_XRD,    MT_D, N,MUL_X,     N,DIV_X,    WEN_N,WA_RD,WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      LBU->      List(Y,     BR_N,  REN_N,REN_Y,A2_SEXT, A1_RS1,DW_XPR,FN_ADD, M_Y,M_XRD,    MT_BU,N,MUL_X,     N,DIV_X,    WEN_N,WA_RD,WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      LHU->      List(Y,     BR_N,  REN_N,REN_Y,A2_SEXT, A1_RS1,DW_XPR,FN_ADD, M_Y,M_XRD,    MT_HU,N,MUL_X,     N,DIV_X,    WEN_N,WA_RD,WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      LWU->      List(xpr64, BR_N,  REN_N,REN_Y,A2_SEXT, A1_RS1,DW_XPR,FN_ADD, M_Y,M_XRD,    MT_WU,N,MUL_X,     N,DIV_X,    WEN_N,WA_RD,WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      SB->       List(Y,     BR_N,  REN_Y,REN_Y,A2_SPLIT,A1_RS1,DW_XPR,FN_ADD, M_Y,M_XWR,    MT_B, N,MUL_X,     N,DIV_X,    WEN_N,WA_X, WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      SH->       List(Y,     BR_N,  REN_Y,REN_Y,A2_SPLIT,A1_RS1,DW_XPR,FN_ADD, M_Y,M_XWR,    MT_H, N,MUL_X,     N,DIV_X,    WEN_N,WA_X, WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      SW->       List(Y,     BR_N,  REN_Y,REN_Y,A2_SPLIT,A1_RS1,DW_XPR,FN_ADD, M_Y,M_XWR,    MT_W, N,MUL_X,     N,DIV_X,    WEN_N,WA_X, WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      SD->       List(xpr64, BR_N,  REN_Y,REN_Y,A2_SPLIT,A1_RS1,DW_XPR,FN_ADD, M_Y,M_XWR,    MT_D, N,MUL_X,     N,DIV_X,    WEN_N,WA_X, WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      LUI->      List(Y,     BR_N,  REN_N,REN_Y,A2_0,    A1_LUI,DW_XPR,FN_ADD, M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_Y,WA_RD,WB_ALU,REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      SLTI ->    List(Y,     BR_N,  REN_N,REN_Y,A2_SEXT, A1_RS1,DW_XPR,FN_SLT, M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_Y,WA_RD,WB_ALU,REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      SLTIU->    List(Y,     BR_N,  REN_N,REN_Y,A2_SEXT, A1_RS1,DW_XPR,FN_SLTU,M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_Y,WA_RD,WB_ALU,REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      ANDI->     List(Y,     BR_N,  REN_N,REN_Y,A2_SEXT, A1_RS1,DW_XPR,FN_AND, M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_Y,WA_RD,WB_ALU,REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      ORI->      List(Y,     BR_N,  REN_N,REN_Y,A2_SEXT, A1_RS1,DW_XPR,FN_OR,  M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_Y,WA_RD,WB_ALU,REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      XORI->     List(Y,     BR_N,  REN_N,REN_Y,A2_SEXT, A1_RS1,DW_XPR,FN_XOR, M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_Y,WA_RD,WB_ALU,REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      SLLI->     List(Y,     BR_N,  REN_N,REN_Y,A2_SEXT, A1_RS1,DW_XPR,FN_SL,  M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_Y,WA_RD,WB_ALU,REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      SRLI->     List(Y_SH,  BR_N,  REN_N,REN_Y,A2_SEXT, A1_RS1,DW_XPR,FN_SR,  M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_Y,WA_RD,WB_ALU,REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      SRAI->     List(Y_SH,  BR_N,  REN_N,REN_Y,A2_SEXT, A1_RS1,DW_XPR,FN_SRA, M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_Y,WA_RD,WB_ALU,REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      ADD->      List(Y,     BR_N,  REN_Y,REN_Y,A2_RS2,  A1_RS1,DW_XPR,FN_ADD, M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_Y,WA_RD,WB_ALU,REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      SUB->      List(Y,     BR_N,  REN_Y,REN_Y,A2_RS2,  A1_RS1,DW_XPR,FN_SUB, M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_Y,WA_RD,WB_ALU,REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      SLT->      List(Y,     BR_N,  REN_Y,REN_Y,A2_RS2,  A1_RS1,DW_XPR,FN_SLT, M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_Y,WA_RD,WB_ALU,REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      SLTU->     List(Y,     BR_N,  REN_Y,REN_Y,A2_RS2,  A1_RS1,DW_XPR,FN_SLTU,M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_Y,WA_RD,WB_ALU,REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      riscvAND-> List(Y,     BR_N,  REN_Y,REN_Y,A2_RS2,  A1_RS1,DW_XPR,FN_AND, M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_Y,WA_RD,WB_ALU,REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      riscvOR->  List(Y,     BR_N,  REN_Y,REN_Y,A2_RS2,  A1_RS1,DW_XPR,FN_OR,  M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_Y,WA_RD,WB_ALU,REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      riscvXOR-> List(Y,     BR_N,  REN_Y,REN_Y,A2_RS2,  A1_RS1,DW_XPR,FN_XOR, M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_Y,WA_RD,WB_ALU,REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      SLL->      List(Y,     BR_N,  REN_Y,REN_Y,A2_RS2,  A1_RS1,DW_XPR,FN_SL,  M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_Y,WA_RD,WB_ALU,REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      SRL->      List(Y,     BR_N,  REN_Y,REN_Y,A2_RS2,  A1_RS1,DW_XPR,FN_SR,  M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_Y,WA_RD,WB_ALU,REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      SRA->      List(Y,     BR_N,  REN_Y,REN_Y,A2_RS2,  A1_RS1,DW_XPR,FN_SRA, M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_Y,WA_RD,WB_ALU,REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      ADDIW->    List(xpr64, BR_N,  REN_N,REN_Y,A2_SEXT, A1_RS1,DW_32,FN_ADD,  M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_Y,WA_RD,WB_ALU,REN_N,WEN_N,N,N,N,N),   
 | 
				
			||||||
 | 
					      SLLIW->    List(xpr64, BR_N,  REN_N,REN_Y,A2_SEXT, A1_RS1,DW_32,FN_SL,   M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_Y,WA_RD,WB_ALU,REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      SRLIW->    List(xpr64, BR_N,  REN_N,REN_Y,A2_SEXT, A1_RS1,DW_32,FN_SR,   M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_Y,WA_RD,WB_ALU,REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      SRAIW->    List(xpr64, BR_N,  REN_N,REN_Y,A2_SEXT, A1_RS1,DW_32,FN_SRA,  M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_Y,WA_RD,WB_ALU,REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      ADDW->     List(xpr64, BR_N,  REN_Y,REN_Y,A2_RS2,  A1_RS1,DW_32,FN_ADD,  M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_Y,WA_RD,WB_ALU,REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      SUBW->     List(xpr64, BR_N,  REN_Y,REN_Y,A2_RS2,  A1_RS1,DW_32,FN_SUB,  M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_Y,WA_RD,WB_ALU,REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      SLLW->     List(xpr64, BR_N,  REN_Y,REN_Y,A2_RS2,  A1_RS1,DW_32,FN_SL,   M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_Y,WA_RD,WB_ALU,REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      SRLW->     List(xpr64, BR_N,  REN_Y,REN_Y,A2_RS2,  A1_RS1,DW_32,FN_SR,   M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_Y,WA_RD,WB_ALU,REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      SRAW->     List(xpr64, BR_N,  REN_Y,REN_Y,A2_RS2,  A1_RS1,DW_32,FN_SRA,  M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_Y,WA_RD,WB_ALU,REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      MUL->      List(Y,     BR_N,  REN_Y,REN_Y,A2_X,    A1_X,  DW_X,  FN_X,   M_N,M_X,      MT_X, Y,MUL_64,    N,DIV_X,    WEN_N,WA_RD,WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      MULH->     List(Y,     BR_N,  REN_Y,REN_Y,A2_X,    A1_X,  DW_X,  FN_X,   M_N,M_X,      MT_X, Y,MUL_64H,   N,DIV_X,    WEN_N,WA_RD,WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      MULHU->    List(Y,     BR_N,  REN_Y,REN_Y,A2_X,    A1_X,  DW_X,  FN_X,   M_N,M_X,      MT_X, Y,MUL_64HU,  N,DIV_X,    WEN_N,WA_RD,WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      MULHSU->   List(Y,     BR_N,  REN_Y,REN_Y,A2_X,    A1_X,  DW_X,  FN_X,   M_N,M_X,      MT_X, Y,MUL_64HSU, N,DIV_X,    WEN_N,WA_RD,WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      MULW->     List(xpr64, BR_N,  REN_Y,REN_Y,A2_X,    A1_X,  DW_X,  FN_X,   M_N,M_X,      MT_X, Y,MUL_32,    N,DIV_X,    WEN_N,WA_RD,WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      DIV->      List(Y,     BR_N,  REN_Y,REN_Y,A2_X,    A1_X,  DW_X,  FN_X,   M_N,M_X,      MT_X, N,MUL_X,     Y,DIV_64D,  WEN_N,WA_RD,WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      DIVU->     List(Y,     BR_N,  REN_Y,REN_Y,A2_X,    A1_X,  DW_X,  FN_X,   M_N,M_X,      MT_X, N,MUL_X,     Y,DIV_64DU, WEN_N,WA_RD,WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      REM->      List(Y,     BR_N,  REN_Y,REN_Y,A2_X,    A1_X,  DW_X,  FN_X,   M_N,M_X,      MT_X, N,MUL_X,     Y,DIV_64R,  WEN_N,WA_RD,WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      REMU->     List(Y,     BR_N,  REN_Y,REN_Y,A2_X,    A1_X,  DW_X,  FN_X,   M_N,M_X,      MT_X, N,MUL_X,     Y,DIV_64RU, WEN_N,WA_RD,WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      DIVW->     List(xpr64, BR_N,  REN_Y,REN_Y,A2_X,    A1_X,  DW_X,  FN_X,   M_N,M_X,      MT_X, N,MUL_X,     Y,DIV_32D,  WEN_N,WA_RD,WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      DIVUW->    List(xpr64, BR_N,  REN_Y,REN_Y,A2_X,    A1_X,  DW_X,  FN_X,   M_N,M_X,      MT_X, N,MUL_X,     Y,DIV_32DU, WEN_N,WA_RD,WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      REMW->     List(xpr64, BR_N,  REN_Y,REN_Y,A2_X,    A1_X,  DW_X,  FN_X,   M_N,M_X,      MT_X, N,MUL_X,     Y,DIV_32R,  WEN_N,WA_RD,WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      REMUW->    List(xpr64, BR_N,  REN_Y,REN_Y,A2_X,    A1_X,  DW_X,  FN_X,   M_N,M_X,      MT_X, N,MUL_X,     Y,DIV_32RU, WEN_N,WA_RD,WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      SYSCALL->  List(Y,     BR_N,  REN_N,REN_N,A2_X,    A1_X,  DW_X,  FN_X,   M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_N,WA_X, WB_X,  REN_N,WEN_N,N,N,Y,N),
 | 
				
			||||||
 | 
					      EI->       List(Y,     BR_N,  REN_N,REN_N,A2_X,    A1_X,  DW_X,  FN_X,   M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_N,WA_X, WB_X,  REN_N,WEN_N,N,N,N,Y),
 | 
				
			||||||
 | 
					      DI->       List(Y,     BR_N,  REN_N,REN_N,A2_X,    A1_X,  DW_X,  FN_X,   M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_N,WA_X, WB_X,  REN_N,WEN_N,N,N,N,Y),
 | 
				
			||||||
 | 
					      ERET->     List(Y,     BR_N,  REN_N,REN_N,A2_X,    A1_X,  DW_X,  FN_X,   M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_N,WA_X, WB_X,  REN_N,WEN_N,N,Y,N,Y),
 | 
				
			||||||
 | 
					      FENCE->    List(Y,     BR_N,  REN_N,REN_N,A2_X,    A1_X,  DW_X,  FN_X,   M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_N,WA_X, WB_X,  REN_N,WEN_N,Y,N,N,N),
 | 
				
			||||||
 | 
					      CFLUSH->   List(Y,     BR_N,  REN_Y,REN_N,A2_X,    A1_X,  DW_X,  FN_X,   M_Y,M_FLA,    MT_X, N,MUL_X,     N,DIV_X,    WEN_N,WA_X, WB_X,  REN_N,WEN_N,N,N,N,Y),
 | 
				
			||||||
 | 
					      MFPCR->    List(Y,     BR_N,  REN_N,REN_N,A2_X,    A1_X,  DW_X,  FN_X,   M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_Y,WA_RD,WB_PCR,REN_Y,WEN_N,N,N,N,Y),
 | 
				
			||||||
 | 
					      MTPCR->    List(Y,     BR_N,  REN_N,REN_Y,A2_X,    A1_X,  DW_X,  FN_X,   M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_N,WA_X, WB_X,  REN_N,WEN_Y,N,N,N,Y)
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      // Instructions that have not yet been implemented
 | 
				
			||||||
 | 
					/*  
 | 
				
			||||||
 | 
					      // floating point
 | 
				
			||||||
 | 
					      FLW->      List(FPU_Y, BR_N,  REN_N,REN_Y,A2_SEXT, A1_RS1,DW_XPR,FN_ADD, M_Y,M_FRD,    MT_WU,N,MUL_X,     N,DIV_X,    WEN_N,WA_X, WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      FLD->      List(FPU_Y, BR_N,  REN_N,REN_Y,A2_SEXT, A1_RS1,DW_XPR,FN_ADD, M_Y,M_FRD,    MT_D, N,MUL_X,     N,DIV_X,    WEN_N,WA_X, WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      FSW->      List(FPU_Y, BR_N,  REN_Y,REN_Y,A2_SPLIT,A1_RS1,DW_XPR,FN_ADD, M_Y,M_FWR,    MT_W, N,MUL_X,     N,DIV_X,    WEN_N,WA_X, WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      FSD->      List(FPU_Y, BR_N,  REN_Y,REN_Y,A2_SPLIT,A1_RS1,DW_XPR,FN_ADD, M_Y,M_FWR,    MT_D, N,MUL_X,     N,DIV_X,    WEN_N,WA_X, WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      // atomic memory operations
 | 
				
			||||||
 | 
					      AMOADD_W-> List(Y,     BR_N,  REN_Y,REN_Y,A2_0,    A1_RS1,DW_XPR,FN_ADD, M_Y,M_XA_ADD, MT_W, N,MUL_X,     N,DIV_X,    WEN_N,WA_RD,WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      AMOSWAP_W->List(Y,     BR_N,  REN_Y,REN_Y,A2_0,    A1_RS1,DW_XPR,FN_ADD, M_Y,M_XA_SWAP,MT_W, N,MUL_X,     N,DIV_X,    WEN_N,WA_RD,WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      AMOAND_W-> List(Y,     BR_N,  REN_Y,REN_Y,A2_0,    A1_RS1,DW_XPR,FN_ADD, M_Y,M_XA_AND, MT_W, N,MUL_X,     N,DIV_X,    WEN_N,WA_RD,WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      AMOOR_W->  List(Y,     BR_N,  REN_Y,REN_Y,A2_0,    A1_RS1,DW_XPR,FN_ADD, M_Y,M_XA_OR,  MT_W, N,MUL_X,     N,DIV_X,    WEN_N,WA_RD,WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      AMOMIN_W-> List(Y,     BR_N,  REN_Y,REN_Y,A2_0,    A1_RS1,DW_XPR,FN_ADD, M_Y,M_XA_MIN, MT_W, N,MUL_X,     N,DIV_X,    WEN_N,WA_RD,WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      AMOMAX_W-> List(Y,     BR_N,  REN_Y,REN_Y,A2_0,    A1_RS1,DW_XPR,FN_ADD, M_Y,M_XA_MAX, MT_W, N,MUL_X,     N,DIV_X,    WEN_N,WA_RD,WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      AMOMINU_W->List(Y,     BR_N,  REN_Y,REN_Y,A2_0,    A1_RS1,DW_XPR,FN_ADD, M_Y,M_XA_MINU,MT_W, N,MUL_X,     N,DIV_X,    WEN_N,WA_RD,WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      AMOMAXU_W->List(Y,     BR_N,  REN_Y,REN_Y,A2_0,    A1_RS1,DW_XPR,FN_ADD, M_Y,M_XA_MAXU,MT_W, N,MUL_X,     N,DIV_X,    WEN_N,WA_RD,WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      AMOADD_D-> List(xpr64, BR_N,  REN_Y,REN_Y,A2_0,    A1_RS1,DW_XPR,FN_ADD, M_Y,M_XA_ADD, MT_D, N,MUL_X,     N,DIV_X,    WEN_N,WA_RD,WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      AMOSWAP_D->List(xpr64, BR_N,  REN_Y,REN_Y,A2_0,    A1_RS1,DW_XPR,FN_ADD, M_Y,M_XA_SWAP,MT_D, N,MUL_X,     N,DIV_X,    WEN_N,WA_RD,WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      AMOAND_D-> List(xpr64, BR_N,  REN_Y,REN_Y,A2_0,    A1_RS1,DW_XPR,FN_ADD, M_Y,M_XA_AND, MT_D, N,MUL_X,     N,DIV_X,    WEN_N,WA_RD,WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      AMOOR_D->  List(xpr64, BR_N,  REN_Y,REN_Y,A2_0,    A1_RS1,DW_XPR,FN_ADD, M_Y,M_XA_OR,  MT_D, N,MUL_X,     N,DIV_X,    WEN_N,WA_RD,WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      AMOMIN_D-> List(xpr64, BR_N,  REN_Y,REN_Y,A2_0,    A1_RS1,DW_XPR,FN_ADD, M_Y,M_XA_MIN, MT_D, N,MUL_X,     N,DIV_X,    WEN_N,WA_RD,WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      AMOMAX_D-> List(xpr64, BR_N,  REN_Y,REN_Y,A2_0,    A1_RS1,DW_XPR,FN_ADD, M_Y,M_XA_MAX, MT_D, N,MUL_X,     N,DIV_X,    WEN_N,WA_RD,WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      AMOMINU_D->List(xpr64, BR_N,  REN_Y,REN_Y,A2_0,    A1_RS1,DW_XPR,FN_ADD, M_Y,M_XA_MINU,MT_D, N,MUL_X,     N,DIV_X,    WEN_N,WA_RD,WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      AMOMAXU_D->List(xpr64, BR_N,  REN_Y,REN_Y,A2_0,    A1_RS1,DW_XPR,FN_ADD, M_Y,M_XA_MAXU,MT_D, N,MUL_X,     N,DIV_X,    WEN_N,WA_RD,WB_X,  REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      // miscellaneous
 | 
				
			||||||
 | 
					      RDNPC->    List(Y,     BR_N,  REN_N,REN_Y,A2_SEXT, A1_RS1,DW_XPR,FN_ADD, M_N,M_X,      MT_X, N,MUL_X,     N,DIV_X,    WEN_Y,WA_RD,WB_PC, REN_N,WEN_N,N,N,N,N),
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					     ));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val id_int_val :: id_br_type :: id_renx2 :: id_renx1 :: id_sel_alu2 :: id_sel_alu1 :: id_fn_dw :: id_fn_alu :: csremainder = cs; 
 | 
				
			||||||
 | 
					  val id_mem_val :: id_mem_cmd :: id_mem_type :: id_mul_val :: id_mul_fn :: id_div_val :: id_div_fn :: id_wen :: id_sel_wa :: id_sel_wb :: id_ren_pcr :: id_wen_pcr :: id_sync :: id_eret :: id_syscall :: id_privileged :: Nil = csremainder;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val id_raddr2 = io.dpath.inst(21,17);
 | 
				
			||||||
 | 
					  val id_raddr1 = io.dpath.inst(26,22);
 | 
				
			||||||
 | 
					  val id_waddr  = io.dpath.inst(31,27);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val id_ren2 = id_renx2;
 | 
				
			||||||
 | 
					  val id_ren1 = id_renx1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val id_console_out_val = id_wen_pcr & (id_raddr2 === PCR_CONSOLE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val id_mem_val_masked = id_mem_val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val mem_xload_val   = id_mem_val_masked & (id_mem_cmd === M_XRD);
 | 
				
			||||||
 | 
					  val mem_xstore_val  = id_mem_val_masked & (id_mem_cmd === M_XWR);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val mem_fire        = id_mem_val_masked & ~io.ctrl.killd;
 | 
				
			||||||
 | 
					  val mem_xload_fire  = mem_xload_val & ~io.ctrl.killd;
 | 
				
			||||||
 | 
					  val mem_xstore_fire = mem_xstore_val & ~io.ctrl.killd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val console_out_fire = id_console_out_val & ~io.ctrl.killd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val div_fire = id_div_val & ~io.ctrl.killd;
 | 
				
			||||||
 | 
					  val mul_fire = id_mul_val & ~io.ctrl.killd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val sboard_wen = mem_xload_fire | div_fire | mul_fire;
 | 
				
			||||||
 | 
					  val sboard_waddr = id_waddr;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  val sboard = new rocketCtrlSboard(); 
 | 
				
			||||||
 | 
					  sboard.io.raddra  := id_raddr2;
 | 
				
			||||||
 | 
					  sboard.io.raddrb  := id_raddr1;
 | 
				
			||||||
 | 
					  sboard.io.raddrc  := id_waddr;
 | 
				
			||||||
 | 
					  sboard.io.set   := sboard_wen.toBool;
 | 
				
			||||||
 | 
					  sboard.io.seta  := sboard_waddr;
 | 
				
			||||||
 | 
					  sboard.io.clr0  := io.wb.wen.toBool;
 | 
				
			||||||
 | 
					  sboard.io.clr0a ^^ io.wb.waddr;
 | 
				
			||||||
 | 
					  sboard.io.clr1  := io.dpath.wen.toBool;
 | 
				
			||||||
 | 
					  sboard.io.clr1a := io.dpath.waddr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val id_stall_raddr2 = sboard.io.stalla;
 | 
				
			||||||
 | 
					  val id_stall_raddr1 = sboard.io.stallb;
 | 
				
			||||||
 | 
					  val id_stall_waddr  = sboard.io.stallc;
 | 
				
			||||||
 | 
					  val id_stall_ra     = sboard.io.stallra;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val mrq = new rocketCtrlCnt(3, 4);   
 | 
				
			||||||
 | 
					  mrq.io.enq   := mem_fire.toBool;
 | 
				
			||||||
 | 
					  mrq.io.deq   ^^ io.mem.mrq_deq;
 | 
				
			||||||
 | 
					  val id_empty_mrq = mrq.io.empty;
 | 
				
			||||||
 | 
					  val id_full_mrq  = mrq.io.full; 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val id_reg_btb_hit    = Reg(width = 1, resetVal = Bool(false));
 | 
				
			||||||
 | 
					  val ex_reg_br_type    = Reg(){UFix(width = 4)};
 | 
				
			||||||
 | 
					  val ex_reg_btb_hit    = Reg(){Bool()};
 | 
				
			||||||
 | 
					  val ex_reg_mem_val    = Reg(){Bool()};
 | 
				
			||||||
 | 
					  val ex_reg_mem_cmd    = Reg(){UFix(width = 4)};
 | 
				
			||||||
 | 
					  val ex_reg_mem_type   = Reg(){UFix(width = 3)};
 | 
				
			||||||
 | 
					  val ex_reg_eret       = Reg(resetVal = Bool(false));
 | 
				
			||||||
 | 
					  val ex_reg_privileged = Reg(resetVal = Bool(false));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  when (!io.ctrl.stalld) {
 | 
				
			||||||
 | 
					    when (io.ctrl.killf) {
 | 
				
			||||||
 | 
					      id_reg_btb_hit <== Bool(false);
 | 
				
			||||||
 | 
					    } 
 | 
				
			||||||
 | 
					    otherwise{
 | 
				
			||||||
 | 
					      id_reg_btb_hit <== io.dpath.btb_hit;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  when (reset.toBool || io.ctrl.killd) {
 | 
				
			||||||
 | 
					    ex_reg_br_type    <== BR_N;
 | 
				
			||||||
 | 
					    ex_reg_btb_hit    <== Bool(false);
 | 
				
			||||||
 | 
					    ex_reg_mem_val    <== Bool(false);
 | 
				
			||||||
 | 
					    ex_reg_mem_cmd    <== UFix(0, 4);
 | 
				
			||||||
 | 
					    ex_reg_mem_type   <== UFix(0, 3);
 | 
				
			||||||
 | 
					    ex_reg_eret       <== Bool(false);
 | 
				
			||||||
 | 
					    ex_reg_privileged <== Bool(false);
 | 
				
			||||||
 | 
					  } 
 | 
				
			||||||
 | 
					  otherwise {
 | 
				
			||||||
 | 
					    ex_reg_br_type    <== id_br_type;
 | 
				
			||||||
 | 
					    ex_reg_btb_hit    <== id_reg_btb_hit;
 | 
				
			||||||
 | 
					    ex_reg_mem_val    <== id_mem_val_masked.toBool;
 | 
				
			||||||
 | 
					    ex_reg_mem_cmd    <== id_mem_cmd;
 | 
				
			||||||
 | 
					    ex_reg_mem_type   <== id_mem_type;
 | 
				
			||||||
 | 
					    ex_reg_eret       <== id_eret.toBool;
 | 
				
			||||||
 | 
					    ex_reg_privileged <== id_privileged.toBool;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val beq  =  io.dpath.br_eq;
 | 
				
			||||||
 | 
					  val bne  = ~io.dpath.br_eq;
 | 
				
			||||||
 | 
					  val blt  =  io.dpath.br_lt;
 | 
				
			||||||
 | 
					  val bltu =  io.dpath.br_ltu;
 | 
				
			||||||
 | 
					  val bge  = ~io.dpath.br_lt;
 | 
				
			||||||
 | 
					  val bgeu = ~io.dpath.br_ltu;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val br_taken =
 | 
				
			||||||
 | 
					    (ex_reg_br_type === BR_EQ) & beq |
 | 
				
			||||||
 | 
					    (ex_reg_br_type === BR_NE) & bne |
 | 
				
			||||||
 | 
					    (ex_reg_br_type === BR_LT) & blt |
 | 
				
			||||||
 | 
					    (ex_reg_br_type === BR_LTU) & bltu |
 | 
				
			||||||
 | 
					    (ex_reg_br_type === BR_GE) & bge |
 | 
				
			||||||
 | 
					    (ex_reg_br_type === BR_GEU) & bgeu;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val jr_taken = (ex_reg_br_type === BR_JR);
 | 
				
			||||||
 | 
					  val j_taken  = (ex_reg_br_type === BR_J);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  io.imem.req_val  := io.host.start;
 | 
				
			||||||
 | 
					//  io.imem.req_val := Bool(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  io.mem.mrq_val   := ex_reg_mem_val;
 | 
				
			||||||
 | 
					  io.mem.mrq_cmd   := ex_reg_mem_cmd;
 | 
				
			||||||
 | 
					  io.mem.mrq_type  := ex_reg_mem_type;
 | 
				
			||||||
 | 
					  io.mem.xsdq_val  := mem_xstore_fire.toBool;
 | 
				
			||||||
 | 
					  io.console.valid := console_out_fire.toBool;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  io.ctrl.sel_pc :=
 | 
				
			||||||
 | 
					    Mux(io.dpath.exception || ex_reg_eret, PC_PCR,
 | 
				
			||||||
 | 
					    Mux(!ex_reg_btb_hit && br_taken, PC_BR,
 | 
				
			||||||
 | 
					    Mux(ex_reg_btb_hit && !br_taken || ex_reg_privileged, PC_EX4,
 | 
				
			||||||
 | 
					    Mux(jr_taken,                    PC_JR,
 | 
				
			||||||
 | 
					    Mux(j_taken,                     PC_J,
 | 
				
			||||||
 | 
					    Mux(io.dpath.btb_hit,            PC_BTB,
 | 
				
			||||||
 | 
					        PC_4))))));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  io.ctrl.wen_btb := ~ex_reg_btb_hit & br_taken;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val take_pc =
 | 
				
			||||||
 | 
					    ~ex_reg_btb_hit & br_taken |
 | 
				
			||||||
 | 
					    ex_reg_btb_hit & ~br_taken |
 | 
				
			||||||
 | 
					    jr_taken |
 | 
				
			||||||
 | 
					    j_taken |
 | 
				
			||||||
 | 
					    io.dpath.exception |
 | 
				
			||||||
 | 
					    ex_reg_privileged |
 | 
				
			||||||
 | 
					    ex_reg_eret; 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  io.ctrl.stallf :=
 | 
				
			||||||
 | 
					    ~take_pc &
 | 
				
			||||||
 | 
					    (
 | 
				
			||||||
 | 
					      ~io.imem.req_rdy |
 | 
				
			||||||
 | 
					      ~io.imem.resp_val |
 | 
				
			||||||
 | 
					      io.ctrl.stalld
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val ctrl_stalld_wo_fpu_rdy =
 | 
				
			||||||
 | 
					    ~take_pc &
 | 
				
			||||||
 | 
					    (
 | 
				
			||||||
 | 
					      id_ren2 & id_stall_raddr2 |
 | 
				
			||||||
 | 
					      id_ren1 & id_stall_raddr1 |
 | 
				
			||||||
 | 
					      (id_sel_wa === WA_RD) & id_stall_waddr |
 | 
				
			||||||
 | 
					      (id_sel_wa === WA_RA) & id_stall_ra |
 | 
				
			||||||
 | 
					      id_mem_val_masked & id_full_mrq |
 | 
				
			||||||
 | 
					      id_sync & (~id_empty_mrq | io.mem.dc_busy) |
 | 
				
			||||||
 | 
					      mem_xstore_val & ~io.mem.xsdq_rdy |
 | 
				
			||||||
 | 
					      id_console_out_val & ~io.console.rdy |
 | 
				
			||||||
 | 
					      id_div_val & ~io.dpath.div_rdy |
 | 
				
			||||||
 | 
					      io.dpath.div_result_val |
 | 
				
			||||||
 | 
					      io.dpath.mul_result_val
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					  // for divider, multiplier writeback
 | 
				
			||||||
 | 
					  val mul_wb = io.dpath.mul_result_val;
 | 
				
			||||||
 | 
					  val div_wb = io.dpath.div_result_val & !mul_wb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  io.ctrl.stalld := ctrl_stalld_wo_fpu_rdy.toBool;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  io.ctrl.killf := take_pc | ~io.imem.resp_val;
 | 
				
			||||||
 | 
					  val ctrl_killd_wo_fpu_rdy = take_pc | ctrl_stalld_wo_fpu_rdy;
 | 
				
			||||||
 | 
					  io.ctrl.killd    := ctrl_killd_wo_fpu_rdy.toBool;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  io.ctrl.ren2     := id_ren2.toBool;
 | 
				
			||||||
 | 
					  io.ctrl.ren1     := id_ren1.toBool;
 | 
				
			||||||
 | 
					  io.ctrl.sel_alu2 := id_sel_alu2;
 | 
				
			||||||
 | 
					  io.ctrl.sel_alu1 := id_sel_alu1.toBool;
 | 
				
			||||||
 | 
					  io.ctrl.fn_dw    := id_fn_dw.toBool;
 | 
				
			||||||
 | 
					  io.ctrl.fn_alu   := id_fn_alu;
 | 
				
			||||||
 | 
					  io.ctrl.div_fn   := id_div_fn;
 | 
				
			||||||
 | 
					  io.ctrl.div_val  := id_div_val.toBool;
 | 
				
			||||||
 | 
					  io.ctrl.div_wb   := div_wb;
 | 
				
			||||||
 | 
					  io.ctrl.mul_fn   := id_mul_fn;
 | 
				
			||||||
 | 
					  io.ctrl.mul_val  := id_mul_val.toBool;
 | 
				
			||||||
 | 
					  io.ctrl.mul_wb   := mul_wb;
 | 
				
			||||||
 | 
					  io.ctrl.wen      := id_wen.toBool;
 | 
				
			||||||
 | 
					  io.ctrl.sel_wa   := id_sel_wa.toBool;
 | 
				
			||||||
 | 
					  io.ctrl.sel_wb   := id_sel_wb;
 | 
				
			||||||
 | 
					  io.ctrl.ren_pcr  := id_ren_pcr.toBool;
 | 
				
			||||||
 | 
					  io.ctrl.wen_pcr  := id_wen_pcr.toBool;
 | 
				
			||||||
 | 
					  io.ctrl.eret     := id_eret.toBool;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  io.ctrl.xcpt_illegal    := ~id_int_val.toBool;
 | 
				
			||||||
 | 
					  io.ctrl.xcpt_privileged := (id_privileged & ~io.dpath.status(5)).toBool;
 | 
				
			||||||
 | 
					  io.ctrl.xcpt_fpu        := Bool(false); 
 | 
				
			||||||
 | 
					  io.ctrl.xcpt_syscall    := id_syscall.toBool;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										62
									
								
								rocket/src/main/scala/ctrl_util.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								rocket/src/main/scala/ctrl_util.scala
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
				
			|||||||
 | 
					package Top
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					import Chisel._
 | 
				
			||||||
 | 
					import Node._;
 | 
				
			||||||
 | 
					import Constants._;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ioCtrlSboard extends Bundle()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  val clr0    = Bool('input);
 | 
				
			||||||
 | 
					  val clr0a   = UFix(5, 'input);
 | 
				
			||||||
 | 
					  val clr1    = Bool('input);
 | 
				
			||||||
 | 
					  val clr1a   = UFix(5, 'input);
 | 
				
			||||||
 | 
					  val set     = Bool('input);
 | 
				
			||||||
 | 
					  val seta    = UFix(5, 'input);
 | 
				
			||||||
 | 
					  val raddra  = UFix(5, 'input);
 | 
				
			||||||
 | 
					  val raddrb  = UFix(5, 'input);
 | 
				
			||||||
 | 
					  val raddrc  = UFix(5, 'input);
 | 
				
			||||||
 | 
					  val stalla  = Bool('output);
 | 
				
			||||||
 | 
					  val stallb  = Bool('output);
 | 
				
			||||||
 | 
					  val stallc  = Bool('output);
 | 
				
			||||||
 | 
					  val stallra = Bool('output);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class rocketCtrlSboard extends Component
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  override val io = new ioCtrlSboard();
 | 
				
			||||||
 | 
					  val reg_busy = Reg(width = 32, resetVal = Bits(0, 32));
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  val set_mask  = Mux(io.set, UFix(1,1) << io.seta, UFix(0,32));
 | 
				
			||||||
 | 
					  val clr0_mask = Mux(io.clr0, ~(UFix(1,1) << io.clr0a), ~UFix(0,32));
 | 
				
			||||||
 | 
					  val clr1_mask = Mux(io.clr1, ~(UFix(1,1) << io.clr1a), ~UFix(0,32));
 | 
				
			||||||
 | 
					  reg_busy <== ((reg_busy | set_mask) & clr0_mask) & clr1_mask;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  io.stalla  := reg_busy(io.raddra).toBool;
 | 
				
			||||||
 | 
					  io.stallb  := reg_busy(io.raddrb).toBool;
 | 
				
			||||||
 | 
					  io.stallc  := reg_busy(io.raddrc).toBool;
 | 
				
			||||||
 | 
					  io.stallra := reg_busy(RA).toBool;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ioCtrlCnt extends Bundle()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  val enq   = Bool('input);
 | 
				
			||||||
 | 
					  val deq   = Bool('input);
 | 
				
			||||||
 | 
					  val empty = Bool('output);
 | 
				
			||||||
 | 
					  val full  = Bool('output);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class rocketCtrlCnt(n_bits: Int, limit: Int) extends Component
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  override val io = new ioCtrlCnt();
 | 
				
			||||||
 | 
					  val counter = Reg(width = n_bits, resetVal = UFix(0, n_bits));  
 | 
				
			||||||
 | 
					  when (io.enq && !io.deq) {
 | 
				
			||||||
 | 
					    counter <== counter + UFix(1, n_bits);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  when (!io.enq && io.deq) {
 | 
				
			||||||
 | 
					    counter <== counter - UFix(1, n_bits);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  io.empty := counter === UFix(0,     n_bits);
 | 
				
			||||||
 | 
					  io.full  := counter === UFix(limit, n_bits);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										251
									
								
								rocket/src/main/scala/dcache.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										251
									
								
								rocket/src/main/scala/dcache.scala
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,251 @@
 | 
				
			|||||||
 | 
					package Top {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import Chisel._
 | 
				
			||||||
 | 
					import Node._;
 | 
				
			||||||
 | 
					import Constants._;
 | 
				
			||||||
 | 
					import scala.math._;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// interface between D$ and processor
 | 
				
			||||||
 | 
					class ioDmem(view: List[String] = null) extends Bundle(view) {
 | 
				
			||||||
 | 
					  val req_val   = Bool('input);
 | 
				
			||||||
 | 
					  val req_rdy   = Bool('output);
 | 
				
			||||||
 | 
					  val req_op    = Bits(4, 'input);
 | 
				
			||||||
 | 
					  val req_addr  = UFix(32, 'input);
 | 
				
			||||||
 | 
					  val req_data  = Bits(64, 'input);
 | 
				
			||||||
 | 
					  val req_wmask = Bits(8, 'input);
 | 
				
			||||||
 | 
					  val req_tag   = Bits(12, 'input);
 | 
				
			||||||
 | 
					  val resp_val  = Bool('output);
 | 
				
			||||||
 | 
					  val resp_data = Bits(64, 'output);
 | 
				
			||||||
 | 
					  val resp_tag  = Bits(12, 'output);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// interface between D$ and memory
 | 
				
			||||||
 | 
					class ioDcache(view: List[String] = null) extends Bundle(view) {
 | 
				
			||||||
 | 
					  val req_addr  = UFix(32, 'input);
 | 
				
			||||||
 | 
					  val req_tag   = UFix(3, 'input);
 | 
				
			||||||
 | 
					  val req_val   = Bool('input);
 | 
				
			||||||
 | 
					  val req_rdy   = Bool('output);
 | 
				
			||||||
 | 
					  val req_wdata = Bits(128, 'input);
 | 
				
			||||||
 | 
					  val req_rw    = Bool('input);
 | 
				
			||||||
 | 
					  val resp_data = Bits(128, 'output);
 | 
				
			||||||
 | 
					  val resp_tag  = Bits(3, 'output);
 | 
				
			||||||
 | 
					  val resp_val  = Bool('output);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ioDCacheDM extends Bundle() {
 | 
				
			||||||
 | 
					  val cpu = new ioDmem();
 | 
				
			||||||
 | 
					  val mem = new ioDcache().flip();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// state machine to flush (write back dirty lines, invalidate clean ones) the D$
 | 
				
			||||||
 | 
					class rocketDCacheDM_flush(lines: Int, addrbits: Int) extends Component {
 | 
				
			||||||
 | 
					  val io = new ioDCacheDM();
 | 
				
			||||||
 | 
					  val dcache = new rocketDCacheDM(lines, addrbits);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  val indexbits = ceil(log10(lines)/log10(2)).toInt;
 | 
				
			||||||
 | 
					  val offsetbits = 6;
 | 
				
			||||||
 | 
					  val tagmsb    = addrbits - 1;
 | 
				
			||||||
 | 
					  val taglsb    = indexbits+offsetbits;
 | 
				
			||||||
 | 
					  val indexmsb  = taglsb-1;
 | 
				
			||||||
 | 
					  val indexlsb  = offsetbits;
 | 
				
			||||||
 | 
					  val offsetmsb = indexlsb-1;
 | 
				
			||||||
 | 
					  val offsetlsb = 3;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  val flush_count = Reg(resetVal = UFix(0, indexbits));
 | 
				
			||||||
 | 
					  val flush_resp_count = Reg(resetVal = UFix(0, indexbits));
 | 
				
			||||||
 | 
					  val flushing = Reg(resetVal = Bool(false));
 | 
				
			||||||
 | 
					  val flush_waiting = Reg(resetVal = Bool(false));
 | 
				
			||||||
 | 
					  val r_cpu_req_tag = Reg(resetVal = Bits(0, 12));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  when (io.cpu.req_val && io.cpu.req_rdy && (io.cpu.req_op === M_FLA)) 
 | 
				
			||||||
 | 
					  { 
 | 
				
			||||||
 | 
					    r_cpu_req_tag <== io.cpu.req_tag;
 | 
				
			||||||
 | 
					    flushing <== Bool(true);
 | 
				
			||||||
 | 
					    flush_waiting <== Bool(true);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  when (dcache.io.cpu.req_rdy && 
 | 
				
			||||||
 | 
					        (flush_count === ~Bits(0, indexbits))) { flushing <== Bool(false); }
 | 
				
			||||||
 | 
					  when (dcache.io.cpu.resp_val && 
 | 
				
			||||||
 | 
					        (dcache.io.cpu.resp_tag === r_cpu_req_tag) &&
 | 
				
			||||||
 | 
					        (flush_resp_count === ~Bits(0, indexbits))) { flush_waiting <== Bool(false); }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  when (flushing && dcache.io.cpu.req_rdy) { flush_count <== flush_count + UFix(1,1); }
 | 
				
			||||||
 | 
					  when (flush_waiting && dcache.io.cpu.resp_val && (dcache.io.cpu.resp_tag === r_cpu_req_tag))
 | 
				
			||||||
 | 
					  { flush_resp_count <== flush_resp_count + UFix(1,1); }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  dcache.io.cpu.req_val   := (io.cpu.req_val && (io.cpu.req_op != M_FLA) && !flush_waiting) || flushing;
 | 
				
			||||||
 | 
					  dcache.io.cpu.req_op    := Mux(flushing, M_FLA, io.cpu.req_op);
 | 
				
			||||||
 | 
					  dcache.io.cpu.req_addr  := Mux(flushing, Cat(Bits(0,tagmsb-taglsb+1), flush_count, Bits(0,offsetbits)).toUFix, io.cpu.req_addr);
 | 
				
			||||||
 | 
					  dcache.io.cpu.req_tag   := Mux(flushing, r_cpu_req_tag, io.cpu.req_tag);
 | 
				
			||||||
 | 
					  dcache.io.cpu.req_data  ^^ io.cpu.req_data;
 | 
				
			||||||
 | 
					  dcache.io.cpu.req_wmask ^^ io.cpu.req_wmask;
 | 
				
			||||||
 | 
					  dcache.io.mem           ^^ io.mem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  io.cpu.req_rdy   := dcache.io.cpu.req_rdy && !flush_waiting;
 | 
				
			||||||
 | 
					  io.cpu.resp_data := dcache.io.cpu.resp_data;
 | 
				
			||||||
 | 
					  io.cpu.resp_tag  := dcache.io.cpu.resp_tag;
 | 
				
			||||||
 | 
					  io.cpu.resp_val  := dcache.io.cpu.resp_val & 
 | 
				
			||||||
 | 
					    !(flush_waiting && (io.cpu.resp_tag === r_cpu_req_tag) && (flush_count != ~Bits(0, addrbits)));
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// basic direct mapped data cache, 2 cycle read latency
 | 
				
			||||||
 | 
					// parameters :
 | 
				
			||||||
 | 
					//    lines = # of cache lines
 | 
				
			||||||
 | 
					//    addr_bits = address width (word addressable) bits
 | 
				
			||||||
 | 
					//    64 bit wide cpu port, 128 bit wide memory port, 64 byte cachelines
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class rocketDCacheDM(lines: Int, addrbits: Int) extends Component {
 | 
				
			||||||
 | 
					  val io = new ioDCacheDM();
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  val indexbits = ceil(log10(lines)/log10(2)).toInt;
 | 
				
			||||||
 | 
					  val offsetbits = 6;
 | 
				
			||||||
 | 
					  val tagmsb    = addrbits - 1;
 | 
				
			||||||
 | 
					  val taglsb    = indexbits+offsetbits;
 | 
				
			||||||
 | 
					  val indexmsb  = taglsb-1;
 | 
				
			||||||
 | 
					  val indexlsb  = offsetbits;
 | 
				
			||||||
 | 
					  val offsetmsb = indexlsb-1;
 | 
				
			||||||
 | 
					  val offsetlsb = 3;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  val s_reset :: s_ready :: s_start_writeback :: s_writeback :: s_req_refill :: s_refill :: s_resolve_miss :: Nil = Enum(7) { UFix() };
 | 
				
			||||||
 | 
					  val state = Reg(resetVal = s_reset);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  val r_cpu_req_addr   = Reg(Bits(0, addrbits));
 | 
				
			||||||
 | 
					  val r_r_cpu_req_addr = Reg(r_cpu_req_addr);
 | 
				
			||||||
 | 
					  val r_cpu_req_val    = Reg(Bool(false));
 | 
				
			||||||
 | 
					  val r_cpu_req_data   = Reg(Bits(0,64));
 | 
				
			||||||
 | 
					  val r_cpu_req_op     = Reg(Bits(0,4));
 | 
				
			||||||
 | 
					  val r_cpu_req_wmask  = Reg(Bits(0,8));
 | 
				
			||||||
 | 
					  val r_cpu_req_tag    = Reg(Bits(0,12));
 | 
				
			||||||
 | 
					  val r_cpu_resp_tag   = Reg(r_cpu_req_tag);
 | 
				
			||||||
 | 
					  val r_cpu_resp_val   = Reg(Bool(false));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  when (io.cpu.req_val && io.cpu.req_rdy) { 
 | 
				
			||||||
 | 
					      r_cpu_req_addr  <== io.cpu.req_addr;
 | 
				
			||||||
 | 
					      r_cpu_req_data  <== io.cpu.req_data;
 | 
				
			||||||
 | 
					      r_cpu_req_op    <== io.cpu.req_op;
 | 
				
			||||||
 | 
					      r_cpu_req_wmask <== io.cpu.req_wmask;
 | 
				
			||||||
 | 
					      r_cpu_req_tag   <== io.cpu.req_tag; }
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					  val req_load  = (r_cpu_req_op === M_XRD);
 | 
				
			||||||
 | 
					  val req_store = (r_cpu_req_op === M_XWR);
 | 
				
			||||||
 | 
					  val req_flush = (r_cpu_req_op === M_FLA);
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					  when (io.cpu.req_rdy) { r_cpu_req_val <== io.cpu.req_val; }
 | 
				
			||||||
 | 
					  otherwise { r_cpu_req_val <== Bool(false); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // counter
 | 
				
			||||||
 | 
					  val rr_count = Reg(resetVal = UFix(0,2));
 | 
				
			||||||
 | 
					  val rr_count_next = rr_count + UFix(1);
 | 
				
			||||||
 | 
					  when (((state === s_refill) && io.mem.resp_val) || ((state === s_writeback) && io.mem.req_rdy)) 
 | 
				
			||||||
 | 
					      { rr_count <== rr_count_next; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // tag array
 | 
				
			||||||
 | 
					  val tag_we    = (state === s_resolve_miss);
 | 
				
			||||||
 | 
					  val tag_waddr = r_cpu_req_addr(indexmsb, indexlsb).toUFix;
 | 
				
			||||||
 | 
					  val tag_wdata = r_cpu_req_addr(tagmsb, taglsb);
 | 
				
			||||||
 | 
					  val tag_array = Mem(lines, tag_we, tag_waddr, tag_wdata);
 | 
				
			||||||
 | 
					  val tag_raddr = Mux((state === s_ready), io.cpu.req_addr(indexmsb, indexlsb).toUFix, r_cpu_req_addr(indexmsb, indexlsb).toUFix);
 | 
				
			||||||
 | 
					  val tag_rdata = Reg(tag_array.read(tag_raddr));
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  // valid bit array
 | 
				
			||||||
 | 
					  val vb_array = Reg(resetVal = Bits(0, lines));
 | 
				
			||||||
 | 
					  val vb_rdata = Reg(vb_array(tag_raddr));
 | 
				
			||||||
 | 
					  when (tag_we && !req_flush) { vb_array <== vb_array.bitSet(r_cpu_req_addr(indexmsb, indexlsb).toUFix, UFix(1,1)); }
 | 
				
			||||||
 | 
					  when (tag_we &&  req_flush) { vb_array <== vb_array.bitSet(r_cpu_req_addr(indexmsb, indexlsb).toUFix, UFix(0,1)); }
 | 
				
			||||||
 | 
					          
 | 
				
			||||||
 | 
					  val tag_valid = vb_rdata.toBool;
 | 
				
			||||||
 | 
					  val tag_match = tag_valid && !req_flush && (tag_rdata === r_cpu_req_addr(tagmsb, taglsb));
 | 
				
			||||||
 | 
					  val store = ((state === s_ready) && r_cpu_req_val && req_store && tag_match ) ||
 | 
				
			||||||
 | 
					              ((state === s_resolve_miss) && req_store);           
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // dirty bit array
 | 
				
			||||||
 | 
					  val db_array  = Reg(resetVal = Bits(0, lines));
 | 
				
			||||||
 | 
					  val db_rdata  = Reg(db_array(tag_raddr));
 | 
				
			||||||
 | 
					  val tag_dirty = db_rdata.toBool;
 | 
				
			||||||
 | 
					  when (store)  { db_array <== db_array.bitSet(r_cpu_req_addr(indexmsb, indexlsb).toUFix, UFix(1,1)); }
 | 
				
			||||||
 | 
					  when (tag_we) { db_array <== db_array.bitSet(r_cpu_req_addr(indexmsb, indexlsb).toUFix, UFix(0,1)); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // data array
 | 
				
			||||||
 | 
					  val data_array_we = ((state === s_refill) && io.mem.resp_val) || store;
 | 
				
			||||||
 | 
					  val data_array_waddr = Mux((state === s_refill), 
 | 
				
			||||||
 | 
					  							 Cat(r_cpu_req_addr(indexmsb, indexlsb), rr_count).toUFix, 
 | 
				
			||||||
 | 
					  							 r_cpu_req_addr(indexmsb, offsetmsb-1).toUFix);
 | 
				
			||||||
 | 
					  							 
 | 
				
			||||||
 | 
					  val data_array_wdata = Mux((state === s_refill), io.mem.resp_data, Cat(r_cpu_req_data, r_cpu_req_data));
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  val req_wmask_expand = Cat(Fill(8, r_cpu_req_wmask(7)),
 | 
				
			||||||
 | 
					  							 Fill(8, r_cpu_req_wmask(6)),
 | 
				
			||||||
 | 
					  							 Fill(8, r_cpu_req_wmask(5)),
 | 
				
			||||||
 | 
					  							 Fill(8, r_cpu_req_wmask(4)),
 | 
				
			||||||
 | 
					  							 Fill(8, r_cpu_req_wmask(3)),
 | 
				
			||||||
 | 
					  							 Fill(8, r_cpu_req_wmask(2)),
 | 
				
			||||||
 | 
					  							 Fill(8, r_cpu_req_wmask(1)),
 | 
				
			||||||
 | 
					  							 Fill(8, r_cpu_req_wmask(0)));
 | 
				
			||||||
 | 
					  							 
 | 
				
			||||||
 | 
					  val store_wmask = Mux(r_cpu_req_addr(offsetlsb).toBool, 
 | 
				
			||||||
 | 
					  						Cat(req_wmask_expand, Bits(0,64)),
 | 
				
			||||||
 | 
					  						Cat(Bits(0,64), req_wmask_expand));
 | 
				
			||||||
 | 
					                                    
 | 
				
			||||||
 | 
					  val data_array_wmask = Mux((state === s_refill), ~Bits(0,128), store_wmask);  
 | 
				
			||||||
 | 
					  val data_array       = Mem(lines*4, data_array_we, data_array_waddr, data_array_wdata, wrMask = data_array_wmask, resetVal = null);
 | 
				
			||||||
 | 
					  val data_array_raddr = Mux((state === s_writeback) && io.mem.req_rdy, Cat(r_cpu_req_addr(indexmsb, indexlsb), rr_count_next).toUFix,
 | 
				
			||||||
 | 
					                             Mux((state === s_start_writeback) || (state === s_writeback), Cat(r_cpu_req_addr(indexmsb, indexlsb), rr_count).toUFix,
 | 
				
			||||||
 | 
					                             r_cpu_req_addr(indexmsb, offsetmsb-1)));
 | 
				
			||||||
 | 
					  val data_array_rdata = Reg(data_array.read(data_array_raddr));
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  // output signals
 | 
				
			||||||
 | 
					  io.cpu.req_rdy   := (state === s_ready) && (!r_cpu_req_val || tag_match);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  when ((((state === s_ready) && r_cpu_req_val && tag_match) || (state === s_resolve_miss)) && !req_store)
 | 
				
			||||||
 | 
					    { r_cpu_resp_val <== Bool(true); }
 | 
				
			||||||
 | 
					  otherwise { r_cpu_resp_val <== Bool(false); }  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  io.cpu.resp_val  := r_cpu_resp_val;
 | 
				
			||||||
 | 
					  io.cpu.resp_data := Mux(r_r_cpu_req_addr(offsetlsb).toBool, data_array_rdata(127, 64), data_array_rdata(63,0));
 | 
				
			||||||
 | 
					  io.cpu.resp_tag  := r_cpu_resp_tag;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  io.mem.req_val  := (state === s_req_refill) || (state === s_writeback);
 | 
				
			||||||
 | 
					  io.mem.req_rw   := (state === s_writeback);
 | 
				
			||||||
 | 
					  io.mem.req_wdata := data_array_rdata;
 | 
				
			||||||
 | 
					  io.mem.req_tag  := UFix(0);
 | 
				
			||||||
 | 
					  io.mem.req_addr := Mux(state === s_writeback, 
 | 
				
			||||||
 | 
					                         Cat(tag_rdata, r_cpu_req_addr(indexmsb, indexlsb), rr_count).toUFix, 
 | 
				
			||||||
 | 
					                         Cat(r_cpu_req_addr(tagmsb, indexlsb), Bits(0,2)).toUFix);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // control state machine
 | 
				
			||||||
 | 
					  switch (state) {
 | 
				
			||||||
 | 
					    is (s_reset) {
 | 
				
			||||||
 | 
					      state <== s_ready;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    is (s_ready) {
 | 
				
			||||||
 | 
					      when (~r_cpu_req_val)             { state <== s_ready; }
 | 
				
			||||||
 | 
					      when (r_cpu_req_val & tag_match)  { state <== s_ready; }
 | 
				
			||||||
 | 
					      when (tag_valid & tag_dirty)      { state <== s_start_writeback; }
 | 
				
			||||||
 | 
					      when (req_flush)                  { state <== s_resolve_miss; }
 | 
				
			||||||
 | 
					      otherwise                         { state <== s_req_refill; }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    is (s_start_writeback) {
 | 
				
			||||||
 | 
					      state <== s_writeback;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    is (s_writeback) {
 | 
				
			||||||
 | 
					      when (io.mem.req_rdy && (rr_count === UFix(3,2))) { 
 | 
				
			||||||
 | 
					        when (req_flush) { state <== s_resolve_miss; } 
 | 
				
			||||||
 | 
					        otherwise        { state <== s_req_refill; }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    is (s_req_refill)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      when (io.mem.req_rdy) { state <== s_refill; }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    is (s_refill) {
 | 
				
			||||||
 | 
					      when (io.mem.resp_val && (rr_count === UFix(3,2))) { state <== s_resolve_miss; }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    is (s_resolve_miss) {
 | 
				
			||||||
 | 
					      state <== s_ready;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }  
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										147
									
								
								rocket/src/main/scala/divider.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								rocket/src/main/scala/divider.scala
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,147 @@
 | 
				
			|||||||
 | 
					package Top {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import Chisel._
 | 
				
			||||||
 | 
					import Node._;
 | 
				
			||||||
 | 
					import Constants._;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ioDivider(width: Int) extends Bundle {
 | 
				
			||||||
 | 
					  // requests
 | 
				
			||||||
 | 
					  val div_val   = Bool('input);
 | 
				
			||||||
 | 
					  val div_rdy   = Bool('output);
 | 
				
			||||||
 | 
					  val div_fn    = UFix(4, 'input);
 | 
				
			||||||
 | 
					  val div_waddr = UFix(5, 'input);
 | 
				
			||||||
 | 
					  val dpath_rs1 = Bits(width, 'input);
 | 
				
			||||||
 | 
					  val dpath_rs2 = Bits(width, 'input);
 | 
				
			||||||
 | 
					  // responses
 | 
				
			||||||
 | 
					  val div_result_bits = Bits(width, 'output);
 | 
				
			||||||
 | 
					  val div_result_tag  = UFix(5, 'output);
 | 
				
			||||||
 | 
					  val div_result_val  = Bool('output);
 | 
				
			||||||
 | 
					  val div_result_rdy  = Bool('input);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// class ioDivider extends Bundle {
 | 
				
			||||||
 | 
					//   // requests
 | 
				
			||||||
 | 
					//   val req_val   = Bool('input);
 | 
				
			||||||
 | 
					//   val req_rdy   = Bool('output);
 | 
				
			||||||
 | 
					//   val req_fn    = UFix(3, 'input);
 | 
				
			||||||
 | 
					//   val req_tag = UFix(5, 'input);
 | 
				
			||||||
 | 
					//   val req_rs1   = Bits(64, 'input);
 | 
				
			||||||
 | 
					//   val req_rs2   = Bits(64, 'input);
 | 
				
			||||||
 | 
					//   // responses
 | 
				
			||||||
 | 
					//   val resp_val  = Bool('output);
 | 
				
			||||||
 | 
					//   val resp_data = Bits(64, 'output);
 | 
				
			||||||
 | 
					//   val resp_tag  = UFix(5, 'output);
 | 
				
			||||||
 | 
					// }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class rocketDivider(width : Int) extends Component {
 | 
				
			||||||
 | 
					  val io = new ioDivider(width);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  val s_ready :: s_neg_inputs :: s_busy :: s_neg_outputs :: s_done :: Nil = Enum(5) { UFix() };
 | 
				
			||||||
 | 
					  val state = Reg(resetVal = s_ready);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  val count_bits  = java.math.BigInteger.valueOf(width).bitLength();
 | 
				
			||||||
 | 
					  val count       = Reg(resetVal = UFix(0, count_bits));
 | 
				
			||||||
 | 
					  val divby0      = Reg(resetVal = Bool(false));
 | 
				
			||||||
 | 
					  val neg_quo     = Reg(resetVal = Bool(false));
 | 
				
			||||||
 | 
					  val neg_rem     = Reg(resetVal = Bool(false));
 | 
				
			||||||
 | 
					  val reg_waddr   = Reg(resetVal = UFix(0, 5));
 | 
				
			||||||
 | 
					  val rem         = Reg(resetVal = Bool(false));
 | 
				
			||||||
 | 
					  val half        = Reg(resetVal = Bool(false));
 | 
				
			||||||
 | 
					  val tc          = Reg(resetVal = Bool(false));
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  val divisor     = Reg(resetVal = UFix(0, width));
 | 
				
			||||||
 | 
					  val remainder   = Reg(resetVal = UFix(0, 2*width+1));
 | 
				
			||||||
 | 
					  val subtractor  = remainder(2*width, width).toUFix - divisor;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  val v_tc   = ((io.div_fn === DIV_64D) || (io.div_fn === DIV_64R)) ||
 | 
				
			||||||
 | 
					               ((io.div_fn === DIV_32D) || (io.div_fn === DIV_32R));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val v_rem  = ((io.div_fn === DIV_32R) || (io.div_fn === DIV_32RU)) ||
 | 
				
			||||||
 | 
					               ((io.div_fn === DIV_64R) || (io.div_fn === DIV_64RU));
 | 
				
			||||||
 | 
					             
 | 
				
			||||||
 | 
					  val v_half = ((io.div_fn === DIV_32R) || (io.div_fn === DIV_32RU)) ||
 | 
				
			||||||
 | 
					               ((io.div_fn === DIV_32D) || (io.div_fn === DIV_32DU));
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  // state machine
 | 
				
			||||||
 | 
					  switch (state) {
 | 
				
			||||||
 | 
					    is (s_ready) {
 | 
				
			||||||
 | 
					      when (!io.div_val)  { state <== s_ready; }
 | 
				
			||||||
 | 
					      when (v_tc)         { state <== s_neg_inputs };
 | 
				
			||||||
 | 
					      otherwise           { state <== s_busy; }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    is (s_neg_inputs)     { state <== s_busy; }
 | 
				
			||||||
 | 
					    is (s_busy) {
 | 
				
			||||||
 | 
					      when (count != UFix(width))   { state <== s_busy; }
 | 
				
			||||||
 | 
					      when (!(neg_quo || neg_rem))  { state <== s_done; }
 | 
				
			||||||
 | 
					      otherwise                     { state <== s_neg_outputs; }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    is (s_neg_outputs)              { state <== s_done; }
 | 
				
			||||||
 | 
					    is (s_done) {
 | 
				
			||||||
 | 
					      when (io.div_result_rdy)      { state <== s_ready; }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // if we're doing 32-bit unsigned division, then we don't want the 32-bit
 | 
				
			||||||
 | 
					  // inputs to be sign-extended.
 | 
				
			||||||
 | 
					  val in_lhs = Mux((v_half && !v_tc), 
 | 
				
			||||||
 | 
					                   Cat(Fill(width/2, UFix(0,1)), io.dpath_rs1(width/2-1, 0)),
 | 
				
			||||||
 | 
					                   io.dpath_rs1).toUFix;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val in_rhs = Mux((v_half && !v_tc), 
 | 
				
			||||||
 | 
					                   Cat(Fill(width/2, UFix(0,1)), io.dpath_rs2(width/2-1, 0)),
 | 
				
			||||||
 | 
					                   io.dpath_rs2).toUFix;                   
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					  when ((state === s_ready) && io.div_val) {
 | 
				
			||||||
 | 
					    count <== UFix(0, count_bits);
 | 
				
			||||||
 | 
					    half <== v_half;
 | 
				
			||||||
 | 
					    neg_quo <== Bool(false);
 | 
				
			||||||
 | 
					    neg_rem <== Bool(false);
 | 
				
			||||||
 | 
					    rem <== v_rem;
 | 
				
			||||||
 | 
					    tc <== v_tc;
 | 
				
			||||||
 | 
					    reg_waddr <== io.div_waddr;
 | 
				
			||||||
 | 
					    divby0 <== Bool(true);
 | 
				
			||||||
 | 
					    divisor <== in_rhs;
 | 
				
			||||||
 | 
					    remainder <== Cat(Fill(width+1, UFix(0,1)), in_lhs).toUFix;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  when (state === s_neg_inputs) {
 | 
				
			||||||
 | 
					    neg_rem <== remainder(width-1).toBool;
 | 
				
			||||||
 | 
					    neg_quo <== (remainder(width-1) != divisor(width-1));
 | 
				
			||||||
 | 
					    when (remainder(width-1).toBool) {
 | 
				
			||||||
 | 
					      remainder <== Cat(remainder(2*width, width), -remainder(width-1,0)).toUFix;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    when (divisor(width-1).toBool) {
 | 
				
			||||||
 | 
					      divisor <== subtractor(width-1,0);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  when (state === s_neg_outputs) {
 | 
				
			||||||
 | 
					    when (neg_rem && neg_quo && !divby0) {
 | 
				
			||||||
 | 
					      remainder <== Cat(-remainder(2*width, width+1), remainder(width), -remainder(width-1,0)).toUFix;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    when (neg_quo && !divby0) {
 | 
				
			||||||
 | 
					      remainder <== Cat(remainder(2*width, width), -remainder(width-1,0)).toUFix;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    when (neg_rem) {
 | 
				
			||||||
 | 
					      remainder <== Cat(-remainder(2*width, width+1), remainder(width,0)).toUFix;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    when (divisor(width-1).toBool) {
 | 
				
			||||||
 | 
					      divisor <== subtractor(width-1,0);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  when (state === s_busy) {
 | 
				
			||||||
 | 
					    count <== count + UFix(1);
 | 
				
			||||||
 | 
					    divby0 <== divby0 && !subtractor(width).toBool;
 | 
				
			||||||
 | 
					    remainder <== Mux(subtractor(width).toBool,
 | 
				
			||||||
 | 
					                      Cat(remainder(2*width-1, width), remainder(width-1,0), ~subtractor(width)),
 | 
				
			||||||
 | 
					                      Cat(subtractor(width-1, 0), remainder(width-1,0), ~subtractor(width))).toUFix;
 | 
				
			||||||
 | 
					  }  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val result = Mux(rem, remainder(2*width, width+1), remainder(width-1,0));
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  io.div_result_bits := Mux(half, Cat(Fill(width/2, result(width/2-1)), result(width/2-1,0)), result);
 | 
				
			||||||
 | 
					  io.div_rdy := (state === s_ready);
 | 
				
			||||||
 | 
					  io.div_result_tag := reg_waddr;
 | 
				
			||||||
 | 
					  io.div_result_val := (state === s_done);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										345
									
								
								rocket/src/main/scala/dpath.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										345
									
								
								rocket/src/main/scala/dpath.scala
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,345 @@
 | 
				
			|||||||
 | 
					package Top {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import Chisel._
 | 
				
			||||||
 | 
					import Node._;
 | 
				
			||||||
 | 
					import Constants._
 | 
				
			||||||
 | 
					import Instructions._
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ioDpath extends Bundle()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  val btb_hit = Bool('output);
 | 
				
			||||||
 | 
					  val inst    = Bits(32, 'output);
 | 
				
			||||||
 | 
					  val rs2     = Bits(64, 'output);
 | 
				
			||||||
 | 
					  val rs1     = Bits(64, 'output);
 | 
				
			||||||
 | 
					  val br_eq   = Bool('output);
 | 
				
			||||||
 | 
					  val br_lt   = Bool('output);
 | 
				
			||||||
 | 
					  val br_ltu  = Bool('output);
 | 
				
			||||||
 | 
					  val div_result_val = Bool('output);
 | 
				
			||||||
 | 
					  val div_rdy = Bool('output);
 | 
				
			||||||
 | 
					  val mul_result_val = Bool('output);
 | 
				
			||||||
 | 
					  val wen     = Bool('output);
 | 
				
			||||||
 | 
					  val waddr   = UFix(5, 'output);
 | 
				
			||||||
 | 
					  val alu_out = UFix(64, 'output);
 | 
				
			||||||
 | 
					  val exception = Bool('output);
 | 
				
			||||||
 | 
					  val status  = Bits(8, 'output);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ioDpathImem extends Bundle()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  val req_addr  = UFix(32, 'output);
 | 
				
			||||||
 | 
					  val resp_data = Bits(32, 'input);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ioDpathWB extends Bundle()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  val waddr = UFix(5, 'input);
 | 
				
			||||||
 | 
					  val wen   = Bool('input);
 | 
				
			||||||
 | 
					  val wdata = Bits(64, 'input);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ioDpathAll extends Bundle()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  val dpath = new ioDpath();
 | 
				
			||||||
 | 
					  val host  = new ioHost();
 | 
				
			||||||
 | 
					  val ctrl  = new ioCtrl().flip();
 | 
				
			||||||
 | 
					  val debug = new ioDebug();
 | 
				
			||||||
 | 
					  val wb    = new ioDpathWB();
 | 
				
			||||||
 | 
					  val imem  = new ioDpathImem();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class rocketDpath extends Component
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  val io  = new ioDpathAll();
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  val btb = new rocketDpathBTB(); 
 | 
				
			||||||
 | 
					  val if_btb_target = btb.io.target;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val pcr = new rocketDpathPCR(); 
 | 
				
			||||||
 | 
					  val ex_pcr = pcr.io.r.data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val alu = new rocketDpathALU(); 
 | 
				
			||||||
 | 
					  val ex_alu_out = alu.io.out; 
 | 
				
			||||||
 | 
					  val ex_jr_target = ex_alu_out(31,0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val div = new rocketDivider(64);
 | 
				
			||||||
 | 
					  val div_result = div.io.div_result_bits;
 | 
				
			||||||
 | 
					  val div_result_tag = div.io.div_result_tag;
 | 
				
			||||||
 | 
					  val div_result_val = div.io.div_result_val;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  val mul = new rocketMultiplier();
 | 
				
			||||||
 | 
					  val mul_result = mul.io.result; 
 | 
				
			||||||
 | 
					  val mul_result_tag = mul.io.result_tag; 
 | 
				
			||||||
 | 
					  val mul_result_val = mul.io.result_val;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
						val rfile = new rocketDpathRegfile();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // instruction fetch definitions
 | 
				
			||||||
 | 
					  val if_reg_pc     = Reg(width = 32, resetVal = UFix(0, 32));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // instruction decode definitions
 | 
				
			||||||
 | 
					  val id_reg_pc        = Reg(){UFix(width = 32)};
 | 
				
			||||||
 | 
					  val id_reg_pc_plus4  = Reg(){UFix(width = 32)};
 | 
				
			||||||
 | 
					  val id_reg_inst      = Reg(width = 32, resetVal = NOP);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // execute definitions
 | 
				
			||||||
 | 
					  val ex_reg_pc             = Reg(width = 32, resetVal = UFix(0, 32));
 | 
				
			||||||
 | 
					  val ex_reg_pc_plus4       = Reg(width = 32, resetVal = UFix(0, 32));
 | 
				
			||||||
 | 
					  val ex_reg_inst           = Reg(width = 32, resetVal = Bits(0, 32));
 | 
				
			||||||
 | 
					  val ex_reg_raddr2         = Reg(width = 5, resetVal = UFix(0, 5));
 | 
				
			||||||
 | 
					  val ex_reg_raddr1         = Reg(width = 5, resetVal = UFix(0, 5));
 | 
				
			||||||
 | 
					  val ex_reg_rs2            = Reg(width = 64, resetVal = Bits(0, 64));
 | 
				
			||||||
 | 
					  val ex_reg_rs1            = Reg(width = 64, resetVal = Bits(0, 64));
 | 
				
			||||||
 | 
					  val ex_reg_waddr          = Reg(width = 5, resetVal = UFix(0, 5));
 | 
				
			||||||
 | 
					  val ex_reg_ctrl_sel_alu2  = Reg(width = 2, resetVal = A2_X);
 | 
				
			||||||
 | 
					  val ex_reg_ctrl_sel_alu1  = Reg(width = 1, resetVal = A1_X);
 | 
				
			||||||
 | 
					  val ex_reg_ctrl_fn_dw     = Reg(width = 1, resetVal = DW_X);
 | 
				
			||||||
 | 
					  val ex_reg_ctrl_fn_alu    = Reg(width = 4, resetVal = FN_X);
 | 
				
			||||||
 | 
					  val ex_reg_ctrl_ll_wb     = Reg(width = 1, resetVal = Bool(false));
 | 
				
			||||||
 | 
					  val ex_reg_ctrl_mul_val   = Reg(width = 1, resetVal = Bool(false));
 | 
				
			||||||
 | 
					  val ex_reg_ctrl_mul_fn    = Reg(width = 3, resetVal = MUL_X);
 | 
				
			||||||
 | 
					  val ex_reg_ctrl_div_val   = Reg(width = 1, resetVal = Bool(false));
 | 
				
			||||||
 | 
					  val ex_reg_ctrl_div_fn    = Reg(width = 4, resetVal = DIV_X);
 | 
				
			||||||
 | 
					  val ex_reg_ctrl_sel_wb    = Reg(width = 3, resetVal = WB_X);
 | 
				
			||||||
 | 
					  val ex_reg_ctrl_wen       = Reg(width = 1, resetVal = Bool(false));
 | 
				
			||||||
 | 
					  val ex_reg_ctrl_ren_pcr   = Reg(width = 1, resetVal = Bool(false));
 | 
				
			||||||
 | 
					  val ex_reg_ctrl_wen_pcr   = Reg(width = 1, resetVal = Bool(false));
 | 
				
			||||||
 | 
					  val ex_reg_ctrl_eret      = Reg(width = 1, resetVal = Bool(false));
 | 
				
			||||||
 | 
					  val ex_reg_ctrl_exception = Reg(width = 1, resetVal = Bool(false));
 | 
				
			||||||
 | 
					  val ex_reg_ctrl_cause     = Reg(width = 5, resetVal = UFix(0,5));
 | 
				
			||||||
 | 
						val ex_wdata						  = Wire() { Bits() };
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
					  // instruction fetch stage
 | 
				
			||||||
 | 
					  val if_pc_plus4 = if_reg_pc + UFix(4, 32);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val ex_sign_extend = 
 | 
				
			||||||
 | 
					    Cat(Fill(52, ex_reg_inst(21)), ex_reg_inst(21,10));
 | 
				
			||||||
 | 
					  val ex_sign_extend_split = 
 | 
				
			||||||
 | 
					    Cat(Fill(52, ex_reg_inst(31)), ex_reg_inst(31,27), ex_reg_inst(16,10));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val branch_adder_rhs =
 | 
				
			||||||
 | 
					    Mux(io.ctrl.sel_pc === PC_BR, Cat(ex_sign_extend_split(30,0), UFix(0, 1)),
 | 
				
			||||||
 | 
					        Cat(Fill(6, ex_reg_inst(31)), ex_reg_inst(31,7),          UFix(0, 1)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val ex_branch_target = ex_reg_pc + branch_adder_rhs.toUFix;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  btb.io.correct_target := ex_branch_target;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val if_next_pc =
 | 
				
			||||||
 | 
					    Mux(io.ctrl.sel_pc === PC_4,   if_pc_plus4,
 | 
				
			||||||
 | 
					    Mux(io.ctrl.sel_pc === PC_BTB, if_btb_target,
 | 
				
			||||||
 | 
					    Mux(io.ctrl.sel_pc === PC_EX4, ex_reg_pc_plus4,
 | 
				
			||||||
 | 
					    Mux(io.ctrl.sel_pc === PC_BR,  ex_branch_target,
 | 
				
			||||||
 | 
					    Mux(io.ctrl.sel_pc === PC_J,   ex_branch_target,
 | 
				
			||||||
 | 
					    Mux(io.ctrl.sel_pc === PC_JR,  ex_jr_target.toUFix,
 | 
				
			||||||
 | 
					    Mux(io.ctrl.sel_pc === PC_PCR, ex_pcr(31,0).toUFix,
 | 
				
			||||||
 | 
					        UFix(0, 32))))))));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  when (!io.host.start){
 | 
				
			||||||
 | 
					    if_reg_pc <== UFix(0, 32); //32'hFFFF_FFFC;
 | 
				
			||||||
 | 
					  }  
 | 
				
			||||||
 | 
					  when (!io.ctrl.stallf) {
 | 
				
			||||||
 | 
					    if_reg_pc <== if_next_pc;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  io.imem.req_addr :=
 | 
				
			||||||
 | 
					    Mux(io.ctrl.stallf, if_reg_pc,
 | 
				
			||||||
 | 
					        if_next_pc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  btb.io.current_pc4    := if_pc_plus4;
 | 
				
			||||||
 | 
					  btb.io.hit            ^^ io.dpath.btb_hit;
 | 
				
			||||||
 | 
					  btb.io.wen            ^^ io.ctrl.wen_btb;
 | 
				
			||||||
 | 
					  btb.io.correct_pc4    := ex_reg_pc_plus4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // instruction decode stage
 | 
				
			||||||
 | 
					  when (!io.ctrl.stalld) {
 | 
				
			||||||
 | 
					    id_reg_pc <== if_reg_pc;
 | 
				
			||||||
 | 
					    id_reg_pc_plus4 <== if_pc_plus4; 
 | 
				
			||||||
 | 
					    when(io.ctrl.killf) {
 | 
				
			||||||
 | 
					      id_reg_inst <== NOP;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    otherwise {
 | 
				
			||||||
 | 
					      id_reg_inst <== io.imem.resp_data;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val id_raddr1 = id_reg_inst(26,22).toUFix;
 | 
				
			||||||
 | 
					  val id_raddr2 = id_reg_inst(21,17).toUFix;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// regfile read
 | 
				
			||||||
 | 
					  rfile.io.r0.en   ^^ io.ctrl.ren2;
 | 
				
			||||||
 | 
					  rfile.io.r0.addr := id_raddr2;
 | 
				
			||||||
 | 
					  val id_rdata2 = rfile.io.r0.data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  rfile.io.r1.en   ^^ io.ctrl.ren1;
 | 
				
			||||||
 | 
					  rfile.io.r1.addr := id_raddr1;
 | 
				
			||||||
 | 
					  val id_rdata1 = rfile.io.r1.data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val id_waddr =
 | 
				
			||||||
 | 
					    Mux(io.ctrl.div_wb, div_result_tag,
 | 
				
			||||||
 | 
					    Mux(io.ctrl.mul_wb, mul_result_tag,
 | 
				
			||||||
 | 
					    Mux(io.ctrl.sel_wa === WA_RD, id_reg_inst(31,27).toUFix,
 | 
				
			||||||
 | 
					    Mux(io.ctrl.sel_wa === WA_RA, RA,
 | 
				
			||||||
 | 
					        UFix(0, 5)))));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val id_rs1 =
 | 
				
			||||||
 | 
					  	Mux(io.ctrl.div_wb, div_result,
 | 
				
			||||||
 | 
					  	Mux(io.ctrl.mul_wb, mul_result,
 | 
				
			||||||
 | 
					    Mux(id_raddr1 != UFix(0, 5) && ex_reg_ctrl_wen && id_raddr1 === ex_reg_waddr, ex_wdata,
 | 
				
			||||||
 | 
					        id_rdata1)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val id_rs2 =
 | 
				
			||||||
 | 
					    Mux(id_raddr2 != UFix(0, 5) && ex_reg_ctrl_wen && id_raddr2 === ex_reg_waddr, ex_wdata,
 | 
				
			||||||
 | 
					        id_rdata2);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
						val id_exception = io.ctrl.xcpt_illegal || io.ctrl.xcpt_privileged || io.ctrl.xcpt_fpu || io.ctrl.xcpt_syscall;
 | 
				
			||||||
 | 
						val id_cause = 
 | 
				
			||||||
 | 
							Mux(io.ctrl.xcpt_illegal, UFix(2,5),
 | 
				
			||||||
 | 
							Mux(io.ctrl.xcpt_privileged, UFix(3,5),
 | 
				
			||||||
 | 
							Mux(io.ctrl.xcpt_fpu, UFix(4,5),
 | 
				
			||||||
 | 
							Mux(io.ctrl.xcpt_syscall, UFix(6,5), 
 | 
				
			||||||
 | 
								UFix(0,5)))));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  io.dpath.inst := id_reg_inst;
 | 
				
			||||||
 | 
					  io.dpath.rs1  := id_rs1;
 | 
				
			||||||
 | 
					  io.dpath.rs2  := id_rs2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // execute stage
 | 
				
			||||||
 | 
					  ex_reg_pc             <== id_reg_pc;
 | 
				
			||||||
 | 
					  ex_reg_pc_plus4       <== id_reg_pc_plus4;
 | 
				
			||||||
 | 
					  ex_reg_inst           <== id_reg_inst;
 | 
				
			||||||
 | 
					  ex_reg_raddr2         <== id_raddr2;
 | 
				
			||||||
 | 
					  ex_reg_raddr1         <== id_raddr1;
 | 
				
			||||||
 | 
					  ex_reg_rs2            <== id_rs2;
 | 
				
			||||||
 | 
					  ex_reg_rs1            <== id_rs1;
 | 
				
			||||||
 | 
					  ex_reg_waddr          <== id_waddr;
 | 
				
			||||||
 | 
					  ex_reg_ctrl_sel_alu2  <== io.ctrl.sel_alu2;
 | 
				
			||||||
 | 
					  ex_reg_ctrl_sel_alu1  <== io.ctrl.sel_alu1.toUFix;
 | 
				
			||||||
 | 
					  ex_reg_ctrl_fn_dw     <== io.ctrl.fn_dw.toUFix;
 | 
				
			||||||
 | 
					  ex_reg_ctrl_fn_alu    <== io.ctrl.fn_alu;
 | 
				
			||||||
 | 
					  ex_reg_ctrl_mul_fn    <== io.ctrl.mul_fn;
 | 
				
			||||||
 | 
					  ex_reg_ctrl_div_fn    <== io.ctrl.div_fn;
 | 
				
			||||||
 | 
					  ex_reg_ctrl_ll_wb     <== io.ctrl.div_wb | io.ctrl.mul_wb; // TODO: verify
 | 
				
			||||||
 | 
					  ex_reg_ctrl_sel_wb    <== io.ctrl.sel_wb;
 | 
				
			||||||
 | 
					  ex_reg_ctrl_ren_pcr   <== io.ctrl.ren_pcr;
 | 
				
			||||||
 | 
					  ex_reg_ctrl_cause     <== id_cause;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  when(io.ctrl.killd) {
 | 
				
			||||||
 | 
					    ex_reg_ctrl_div_val 	<== Bool(false);
 | 
				
			||||||
 | 
					    ex_reg_ctrl_mul_val   <== Bool(false);
 | 
				
			||||||
 | 
					    ex_reg_ctrl_wen     	<== Bool(false);
 | 
				
			||||||
 | 
					    ex_reg_ctrl_wen_pcr 	<== Bool(false);
 | 
				
			||||||
 | 
					    ex_reg_ctrl_eret			<== Bool(false);
 | 
				
			||||||
 | 
					  	ex_reg_ctrl_exception <== Bool(false);
 | 
				
			||||||
 | 
					  } 
 | 
				
			||||||
 | 
					  otherwise {
 | 
				
			||||||
 | 
					    ex_reg_ctrl_div_val 	<== io.ctrl.div_val;
 | 
				
			||||||
 | 
					  	ex_reg_ctrl_mul_val   <== io.ctrl.mul_val;
 | 
				
			||||||
 | 
					    ex_reg_ctrl_wen     	<== io.ctrl.wen;
 | 
				
			||||||
 | 
					    ex_reg_ctrl_wen_pcr		<== io.ctrl.wen_pcr;
 | 
				
			||||||
 | 
					    ex_reg_ctrl_eret			<== io.ctrl.eret;
 | 
				
			||||||
 | 
					    ex_reg_ctrl_exception <== id_exception;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val ex_alu_in2 =
 | 
				
			||||||
 | 
					    Mux(ex_reg_ctrl_sel_alu2 === A2_0,     UFix(0, 64),
 | 
				
			||||||
 | 
					    Mux(ex_reg_ctrl_sel_alu2 === A2_SEXT,  ex_sign_extend,
 | 
				
			||||||
 | 
					    Mux(ex_reg_ctrl_sel_alu2 === A2_SPLIT, ex_sign_extend_split,
 | 
				
			||||||
 | 
					    Mux(ex_reg_ctrl_sel_alu2 === A2_RS2,   ex_reg_rs2,
 | 
				
			||||||
 | 
					        UFix(0, 64)))));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val ex_alu_in1 =
 | 
				
			||||||
 | 
					    Mux(ex_reg_ctrl_sel_alu1 === A1_RS1, ex_reg_rs1,
 | 
				
			||||||
 | 
					    Mux(ex_reg_ctrl_sel_alu1 === A1_LUI, Cat(Fill(32, ex_reg_inst(26)),ex_reg_inst(26,7),UFix(0, 12)),
 | 
				
			||||||
 | 
					        UFix(0, 64)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val ex_alu_shamt =
 | 
				
			||||||
 | 
					    Cat(ex_alu_in2(5) & ex_reg_ctrl_fn_dw === DW_64, ex_alu_in2(4,0)).toUFix;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  alu.io.dw    := ex_reg_ctrl_fn_dw;
 | 
				
			||||||
 | 
					  alu.io.fn    := ex_reg_ctrl_fn_alu;
 | 
				
			||||||
 | 
					  alu.io.shamt := ex_alu_shamt.toUFix;
 | 
				
			||||||
 | 
					  alu.io.in2   := ex_alu_in2.toUFix;
 | 
				
			||||||
 | 
					  alu.io.in1   := ex_alu_in1.toUFix;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  // divider
 | 
				
			||||||
 | 
					  div.io.div_fn    := ex_reg_ctrl_div_fn;
 | 
				
			||||||
 | 
					  div.io.div_val   := ex_reg_ctrl_div_val;
 | 
				
			||||||
 | 
					  div.io.div_waddr := ex_reg_waddr;
 | 
				
			||||||
 | 
					  div.io.dpath_rs1 := ex_reg_rs1;
 | 
				
			||||||
 | 
					  div.io.dpath_rs2 := ex_reg_rs2;
 | 
				
			||||||
 | 
					  div.io.div_result_rdy := io.ctrl.div_wb;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  io.dpath.div_rdy 				:= div.io.div_rdy;
 | 
				
			||||||
 | 
					  io.dpath.div_result_val := div.io.div_result_val;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  // multiplier
 | 
				
			||||||
 | 
					  mul.io.mul_val := ex_reg_ctrl_mul_val;
 | 
				
			||||||
 | 
					  mul.io.mul_fn	 := ex_reg_ctrl_mul_fn;
 | 
				
			||||||
 | 
					  mul.io.mul_tag := ex_reg_waddr;
 | 
				
			||||||
 | 
					  mul.io.in0		 := ex_reg_rs1;
 | 
				
			||||||
 | 
					  mul.io.in1		 := ex_reg_rs2;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  io.dpath.mul_result_val := mul.io.result_val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// processor control register i/o
 | 
				
			||||||
 | 
					  pcr.io.host.from_wen ^^ io.host.from_wen;
 | 
				
			||||||
 | 
					  pcr.io.host.from     ^^ io.host.from;
 | 
				
			||||||
 | 
					  pcr.io.host.to       ^^ io.host.to;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pcr.io.r.en   := ex_reg_ctrl_ren_pcr | ex_reg_ctrl_exception | ex_reg_ctrl_eret;
 | 
				
			||||||
 | 
					  pcr.io.r.addr := 
 | 
				
			||||||
 | 
					  	Mux(ex_reg_ctrl_exception, PCR_EVEC, 
 | 
				
			||||||
 | 
					  	Mux(ex_reg_ctrl_eret, PCR_EPC, 
 | 
				
			||||||
 | 
					  		ex_reg_raddr2));
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  pcr.io.w.addr := ex_reg_raddr2;
 | 
				
			||||||
 | 
					  pcr.io.w.en   := ex_reg_ctrl_wen_pcr;
 | 
				
			||||||
 | 
					  pcr.io.w.data := ex_reg_rs1;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  pcr.io.eret      	:= ex_reg_ctrl_eret;
 | 
				
			||||||
 | 
					  pcr.io.exception 	:= ex_reg_ctrl_exception;
 | 
				
			||||||
 | 
					  pcr.io.cause 			:= ex_reg_ctrl_cause;
 | 
				
			||||||
 | 
					  pcr.io.pc					:= ex_reg_pc;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  io.dpath.status   := pcr.io.status;
 | 
				
			||||||
 | 
					//  io.debug 					^^ pcr.io.debug;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					 	io.debug.error_mode  := pcr.io.debug.error_mode;
 | 
				
			||||||
 | 
					 	io.debug.log_control := pcr.io.debug.log_control;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// branch resolution logic
 | 
				
			||||||
 | 
					  io.dpath.br_eq   := (ex_reg_rs1 === ex_reg_rs2);
 | 
				
			||||||
 | 
					  io.dpath.br_ltu  := (ex_reg_rs1.toUFix < ex_reg_rs2.toUFix);
 | 
				
			||||||
 | 
					  io.dpath.br_lt :=
 | 
				
			||||||
 | 
					    (~(ex_reg_rs1(63) ^ ex_reg_rs2(63)) & io.dpath.br_ltu |
 | 
				
			||||||
 | 
					    ex_reg_rs1(63) & ~ex_reg_rs2(63)).toBool;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  io.dpath.alu_out := ex_alu_out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// writeback select mux
 | 
				
			||||||
 | 
					  ex_wdata :=
 | 
				
			||||||
 | 
					    Mux(ex_reg_ctrl_ll_wb, ex_reg_rs1,
 | 
				
			||||||
 | 
					    Mux(ex_reg_ctrl_sel_wb === WB_PC,  ex_reg_pc_plus4,
 | 
				
			||||||
 | 
					    Mux(ex_reg_ctrl_sel_wb === WB_ALU, ex_alu_out,
 | 
				
			||||||
 | 
					    Mux(ex_reg_ctrl_sel_wb === WB_PCR, ex_pcr,
 | 
				
			||||||
 | 
					        Bits(0, 64))))).toBits;
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
						// regfile write
 | 
				
			||||||
 | 
					  rfile.io.w0.addr := ex_reg_waddr;
 | 
				
			||||||
 | 
					  rfile.io.w0.en   := ex_reg_ctrl_wen | ex_reg_ctrl_ll_wb;
 | 
				
			||||||
 | 
					  rfile.io.w0.data := ex_wdata; 
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  rfile.io.w1.addr ^^ io.wb.waddr;
 | 
				
			||||||
 | 
					  rfile.io.w1.en   ^^ io.wb.wen;
 | 
				
			||||||
 | 
					  rfile.io.w1.data ^^ io.wb.wdata;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  // clear scoreboard for "long latency" writebacks
 | 
				
			||||||
 | 
					  io.dpath.wen   := ex_reg_ctrl_ll_wb;
 | 
				
			||||||
 | 
					  io.dpath.waddr := ex_reg_waddr;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  // exception signal to control (for NPC select)
 | 
				
			||||||
 | 
					  io.dpath.exception := ex_reg_ctrl_exception;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										90
									
								
								rocket/src/main/scala/dpath_alu.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								rocket/src/main/scala/dpath_alu.scala
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,90 @@
 | 
				
			|||||||
 | 
					package Top {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import Chisel._
 | 
				
			||||||
 | 
					import Node._;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import Constants._
 | 
				
			||||||
 | 
					import Instructions._
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ioALU extends Bundle(){
 | 
				
			||||||
 | 
					  val dw    = UFix(1, 'input);
 | 
				
			||||||
 | 
					  val fn    = UFix(4, 'input);
 | 
				
			||||||
 | 
					  val shamt = UFix(6, 'input);
 | 
				
			||||||
 | 
					  val in2   = UFix(64, 'input);
 | 
				
			||||||
 | 
					  val in1   = UFix(64, 'input);
 | 
				
			||||||
 | 
					  val out   = UFix(64, 'output);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class rocketDpathALU extends Component
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  override val io = new ioALU();
 | 
				
			||||||
 | 
					  val out64 =
 | 
				
			||||||
 | 
					    MuxCase(Fix(0, 64), Array(
 | 
				
			||||||
 | 
					      (io.fn === FN_ADD) ->                   (io.in1 + io.in2).toFix,
 | 
				
			||||||
 | 
					      (io.fn === FN_SUB) ->                   (io.in1 - io.in2).toFix,
 | 
				
			||||||
 | 
					      (io.fn === FN_SLT) ->                   (io.in1.toFix < io.in2.toFix), //(io.in1 < io.in2)
 | 
				
			||||||
 | 
					      (io.fn === FN_SLTU) ->                  (io.in1 < io.in2).toFix,
 | 
				
			||||||
 | 
					      (io.fn === FN_AND) ->                   (io.in1 & io.in2).toFix,
 | 
				
			||||||
 | 
					      (io.fn === FN_OR) ->                    (io.in1 | io.in2).toFix,
 | 
				
			||||||
 | 
					      (io.fn === FN_XOR) ->                   (io.in1 ^ io.in2).toFix,
 | 
				
			||||||
 | 
					      (io.fn === FN_SL) ->                    (io.in1 << io.shamt).toFix,
 | 
				
			||||||
 | 
					      (io.fn === FN_SR && io.dw === DW_64) -> (io.in1 >> io.shamt).toFix,
 | 
				
			||||||
 | 
					      (io.fn === FN_SR && io.dw === DW_32) -> (Cat(Fix(0, 32),io.in1(31, 0)).toUFix >> io.shamt),
 | 
				
			||||||
 | 
					      (io.fn === FN_SRA) ->                   (io.in1.toFix >>> io.shamt)));
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					  io.out := MuxLookup(io.dw, Fix(0, 64), Array(
 | 
				
			||||||
 | 
					              DW_64 -> out64,
 | 
				
			||||||
 | 
					              DW_32 -> Cat(Fill(32, out64(31)), out64(31,0)).toFix)).toUFix;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					class IoDpathALU extends Bundle {
 | 
				
			||||||
 | 
					  val in0 = Bits(32,'input);
 | 
				
			||||||
 | 
					  val in1 = Bits(32,'input);
 | 
				
			||||||
 | 
					  val fn = Bits(4,'input);
 | 
				
			||||||
 | 
					  val out = Bits(32,'output);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class DpathALU extends Component {
 | 
				
			||||||
 | 
					  val io = new IoDpathALU();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val adder_in0 = MuxCase(io.in0,Array(
 | 
				
			||||||
 | 
					      ((io.fn === FN_SUB) | (io.fn === FN_SLT) | (io.fn === FN_SLTU)) -> (~io.in0)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val adder_in1 = io.in1;
 | 
				
			||||||
 | 
					  val adder_cin = MuxCase(Bits(0),Array(
 | 
				
			||||||
 | 
					      ((io.fn === FN_SUB) | (io.fn === FN_SLT) | (io.fn === FN_SLTU)) -> Bits(1)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Need to make the same width?
 | 
				
			||||||
 | 
					  val adder_out = Cat(Bits(0,1),adder_in1).toUFix + Cat(Bits(0,1),adder_in0).toUFix + adder_cin.toUFix;
 | 
				
			||||||
 | 
					  //adder_out := (adder_in1.toUFix + adder_in0.toUFix + adder_cin.toUFix);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Determine if there is overflow
 | 
				
			||||||
 | 
					  val overflow = (io.in0(31) ^ io.in1(31)) & (adder_out(32) != io.in0(31));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val compare_yes = MuxLookup(io.fn,Bits(0),Array(
 | 
				
			||||||
 | 
					      // If unsigned, do subtraction, and if the result is negative, then slt=true
 | 
				
			||||||
 | 
					      FN_SLTU -> ~adder_out(32),
 | 
				
			||||||
 | 
					      // If signed, do subtraction, and if the result is negative, then slt=true as well
 | 
				
			||||||
 | 
					      // But if there is bad overflow (operands same sign and result is a different sign),
 | 
				
			||||||
 | 
					      // then need to flip
 | 
				
			||||||
 | 
					      FN_SLT -> ~(adder_out(32) ^ overflow)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  io.out := MuxLookup(io.fn,Fix(0),Array(
 | 
				
			||||||
 | 
					    FN_ADD -> adder_out,
 | 
				
			||||||
 | 
					    FN_SUB -> adder_out,
 | 
				
			||||||
 | 
					    FN_SLT -> compare_yes,
 | 
				
			||||||
 | 
					    FN_SLTU -> compare_yes,
 | 
				
			||||||
 | 
					    FN_AND -> (io.in0 & io.in1),
 | 
				
			||||||
 | 
					    FN_OR -> (io.in0 | io.in1),
 | 
				
			||||||
 | 
					    FN_XOR -> (io.in0 ^ io.in1),
 | 
				
			||||||
 | 
					    FN_SL -> (io.in1 << io.in0(4,0).toUFix),
 | 
				
			||||||
 | 
					    FN_SR -> (io.in1 >> io.in0(4,0).toUFix),
 | 
				
			||||||
 | 
					    FN_SRA -> (io.in1.toFix >> io.in0(4,0).toUFix)
 | 
				
			||||||
 | 
					  ));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										184
									
								
								rocket/src/main/scala/dpath_util.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										184
									
								
								rocket/src/main/scala/dpath_util.scala
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,184 @@
 | 
				
			|||||||
 | 
					package Top
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import Chisel._
 | 
				
			||||||
 | 
					import Node._;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import Constants._;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ioDpathBTB extends Bundle()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  val current_pc4    = UFix(32, 'input);
 | 
				
			||||||
 | 
					  val hit            = Bool('output);
 | 
				
			||||||
 | 
					  val target         = UFix(32, 'output);
 | 
				
			||||||
 | 
					  val wen            = Bool('input);
 | 
				
			||||||
 | 
					  val correct_pc4    = UFix(32, 'input);
 | 
				
			||||||
 | 
					  val correct_target = UFix(32, 'input);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class rocketDpathBTB extends Component
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  override val io = new ioDpathBTB();
 | 
				
			||||||
 | 
					  val rst_lwlr_pf  = Mem(4, io.wen, io.correct_pc4(3, 2), UFix(1, 1), resetVal = UFix(0, 1)); 
 | 
				
			||||||
 | 
					  val lwlr_pf      = Mem(4, io.wen, io.correct_pc4(3, 2), 
 | 
				
			||||||
 | 
					                         Cat(io.correct_pc4(31,4), io.correct_target(31,2)), resetVal = UFix(0, 1));
 | 
				
			||||||
 | 
					  val is_val       = rst_lwlr_pf(io.current_pc4(3, 2));
 | 
				
			||||||
 | 
					  val tag_target   = lwlr_pf(io.current_pc4(3, 2));
 | 
				
			||||||
 | 
					  io.hit    := (is_val & (tag_target(57,30) === io.current_pc4(31, 4))).toBool;
 | 
				
			||||||
 | 
					  io.target := Cat(tag_target(29, 0), Bits(0,2)).toUFix;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ioDpathPCR extends Bundle()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  val host  = new ioHost(List("from", "from_wen", "to"));
 | 
				
			||||||
 | 
					  val debug = new ioDebug();
 | 
				
			||||||
 | 
					  val r     = new ioReadPort();
 | 
				
			||||||
 | 
					  val w     = new ioWritePort();
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  val status 		= Bits(8, 'output);
 | 
				
			||||||
 | 
					  val exception = Bool('input);
 | 
				
			||||||
 | 
					  val cause 		= UFix(5, 'input);
 | 
				
			||||||
 | 
					  val pc    		= UFix(32, 'input);
 | 
				
			||||||
 | 
					  val eret  		= Bool('input);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class rocketDpathPCR extends Component
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  override val io = new ioDpathPCR();
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  val HAVE_FPU = Bool(false);
 | 
				
			||||||
 | 
					  val HAVE_VEC = Bool(false);
 | 
				
			||||||
 | 
					  val w = 32;
 | 
				
			||||||
 | 
					  val reg_epc      = Reg(resetVal = Bits(0, w)); 
 | 
				
			||||||
 | 
					  val reg_badvaddr = Reg(resetVal = Bits(0, w)); 
 | 
				
			||||||
 | 
					  val reg_ebase    = Reg(resetVal = Bits(0, w)); 
 | 
				
			||||||
 | 
					  val reg_count    = Reg(resetVal = Bits(0, w)); 
 | 
				
			||||||
 | 
					  val reg_compare  = Reg(resetVal = Bits(0, w)); 
 | 
				
			||||||
 | 
					  val reg_cause    = Reg(resetVal = Bits(0, 5));
 | 
				
			||||||
 | 
					  val reg_tohost   = Reg(resetVal = Bits(0, w)); 
 | 
				
			||||||
 | 
					  val reg_fromhost = Reg(resetVal = Bits(0, w));
 | 
				
			||||||
 | 
					  val reg_k0       = Reg(resetVal = Bits(0, 2*w));
 | 
				
			||||||
 | 
					  val reg_k1       = Reg(resetVal = Bits(0, 2*w));
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  val reg_error_mode  = Reg(resetVal = Bool(false));
 | 
				
			||||||
 | 
					  val reg_log_control = Reg(resetVal = Bool(false));
 | 
				
			||||||
 | 
					  val reg_status_im   = Reg(resetVal = Bits(0,8));
 | 
				
			||||||
 | 
					  val reg_status_sx   = Reg(resetVal = Bool(true));
 | 
				
			||||||
 | 
					  val reg_status_ux   = Reg(resetVal = Bool(true));
 | 
				
			||||||
 | 
					  val reg_status_ef   = Reg(resetVal = Bool(false));
 | 
				
			||||||
 | 
					  val reg_status_ev   = Reg(resetVal = Bool(false));
 | 
				
			||||||
 | 
					  val reg_status_s    = Reg(resetVal = Bool(true));
 | 
				
			||||||
 | 
					  val reg_status_ps   = Reg(resetVal = Bool(false));
 | 
				
			||||||
 | 
					  val reg_status_et   = Reg(resetVal = Bool(false));
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  val reg_status = Cat(reg_status_sx, reg_status_ux, reg_status_s, reg_status_ps, Bits(0,1), reg_status_ev, reg_status_ef, reg_status_et);
 | 
				
			||||||
 | 
					  val rdata = Wire() { Bits() };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  io.status  						:= reg_status;
 | 
				
			||||||
 | 
					  io.host.to 						:= Mux(io.host.from_wen, Bits(0, w), reg_tohost);
 | 
				
			||||||
 | 
					  io.debug.error_mode  	:= reg_error_mode;
 | 
				
			||||||
 | 
					  io.debug.log_control 	:= reg_log_control;
 | 
				
			||||||
 | 
					  io.r.data := rdata;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  when (io.host.from_wen) {
 | 
				
			||||||
 | 
					    reg_tohost   <== Bits(0, w);
 | 
				
			||||||
 | 
					    reg_fromhost <== io.host.from;
 | 
				
			||||||
 | 
					  } 
 | 
				
			||||||
 | 
					  otherwise {
 | 
				
			||||||
 | 
					    when (!io.exception && io.w.en && (io.w.addr === PCR_TOHOST)) {
 | 
				
			||||||
 | 
					      reg_tohost   <== io.w.data(w-1, 0);
 | 
				
			||||||
 | 
					      reg_fromhost <== Bits(0, w);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  when (io.exception && !reg_status_et) {
 | 
				
			||||||
 | 
					  	reg_error_mode <== Bool(true);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  when (io.exception && reg_status_et) {
 | 
				
			||||||
 | 
					  	reg_status_s  <== Bool(true);
 | 
				
			||||||
 | 
					  	reg_status_ps <== reg_status_s;
 | 
				
			||||||
 | 
					  	reg_status_et <== Bool(false);
 | 
				
			||||||
 | 
					  	reg_epc       <== io.pc;
 | 
				
			||||||
 | 
					  	reg_cause     <== io.cause;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  when (!io.exception && io.eret) {
 | 
				
			||||||
 | 
					  	reg_status_s  <== reg_status_ps;
 | 
				
			||||||
 | 
					  	reg_status_et <== Bool(true);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  when (!io.exception && !io.eret && io.w.en) {
 | 
				
			||||||
 | 
					  	when (io.w.addr === PCR_STATUS) {
 | 
				
			||||||
 | 
						    reg_status_im <== io.w.data(15,8);
 | 
				
			||||||
 | 
					      reg_status_sx <== io.w.data(7).toBool;
 | 
				
			||||||
 | 
					      reg_status_ux <== io.w.data(6).toBool;
 | 
				
			||||||
 | 
					      reg_status_s  <== io.w.data(5).toBool;
 | 
				
			||||||
 | 
					      reg_status_ps <== io.w.data(4).toBool;
 | 
				
			||||||
 | 
					      reg_status_ev <== HAVE_VEC && io.w.data(2).toBool;
 | 
				
			||||||
 | 
					      reg_status_ef <== HAVE_FPU && io.w.data(1).toBool;
 | 
				
			||||||
 | 
					      reg_status_et <== io.w.data(0).toBool;
 | 
				
			||||||
 | 
					  	}
 | 
				
			||||||
 | 
					  	when (io.w.addr === PCR_EPC) 			{ reg_epc      		<== io.w.data(w-1,0); }
 | 
				
			||||||
 | 
					  	when (io.w.addr === PCR_BADVADDR) { reg_badvaddr 		<== io.w.data(w-1,0); }
 | 
				
			||||||
 | 
					  	when (io.w.addr === PCR_EVEC) 		{ reg_ebase 			<== io.w.data(w-1,0); }
 | 
				
			||||||
 | 
					  	when (io.w.addr === PCR_COUNT) 		{ reg_count 			<== io.w.data(w-1,0); }
 | 
				
			||||||
 | 
					  	when (io.w.addr === PCR_COMPARE) 	{ reg_compare 		<== io.w.data(w-1,0); }
 | 
				
			||||||
 | 
					  	when (io.w.addr === PCR_CAUSE) 		{ reg_cause 			<== io.w.data(4,0); }
 | 
				
			||||||
 | 
					  	when (io.w.addr === PCR_LOG) 			{ reg_log_control	<== io.w.data(0).toBool; }
 | 
				
			||||||
 | 
					  	when (io.w.addr === PCR_FROMHOST) { reg_fromhost 		<== io.w.data(w-1,0); }
 | 
				
			||||||
 | 
					  	when (io.w.addr === PCR_K0) 			{ reg_k0  				<== io.w.data; }
 | 
				
			||||||
 | 
					  	when (io.w.addr === PCR_K1) 			{ reg_k1  				<== io.w.data; }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  when (!io.r.en) { rdata <== Bits(0,2*w); }
 | 
				
			||||||
 | 
					  switch (io.r.addr) {
 | 
				
			||||||
 | 
					    is (PCR_STATUS) 	{ rdata <== Cat(Bits(0,w+16), reg_status_im, reg_status); }
 | 
				
			||||||
 | 
					    is (PCR_EPC) 			{ rdata <== Cat(Fill(w, reg_epc(w-1)), reg_epc); }
 | 
				
			||||||
 | 
					    is (PCR_BADVADDR) { rdata <== Cat(Fill(w, reg_badvaddr(w-1)), reg_badvaddr); }
 | 
				
			||||||
 | 
					    is (PCR_EVEC) 		{ rdata <== Cat(Fill(w, reg_ebase(w-1)), reg_ebase); }
 | 
				
			||||||
 | 
					    is (PCR_COUNT) 		{ rdata <== Cat(Fill(w, reg_count(w-1)), reg_count); }
 | 
				
			||||||
 | 
					    is (PCR_COMPARE) 	{ rdata <== Cat(Fill(w, reg_compare(w-1)), reg_compare); }
 | 
				
			||||||
 | 
					    is (PCR_CAUSE) 		{ rdata <== Cat(Bits(0,w+27), reg_cause); }
 | 
				
			||||||
 | 
					    is (PCR_MEMSIZE) 	{ rdata <== Bits("h2000", 2*w); }
 | 
				
			||||||
 | 
					    is (PCR_LOG) 	    { rdata <== Cat(Bits(0,63), reg_log_control); }
 | 
				
			||||||
 | 
					    is (PCR_FROMHOST) { rdata <== Cat(Fill(w, reg_fromhost(w-1)), reg_fromhost); }
 | 
				
			||||||
 | 
					    is (PCR_TOHOST)  	{ rdata <== Cat(Fill(w, reg_tohost(w-1)), reg_tohost); }
 | 
				
			||||||
 | 
					    is (PCR_K0) 			{ rdata <== reg_k0; }
 | 
				
			||||||
 | 
					    is (PCR_K1) 			{ rdata <== reg_k1; }
 | 
				
			||||||
 | 
					    otherwise					{ rdata <== Bits(0,2*w); }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ioReadPort extends Bundle()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  val addr = UFix(5, 'input);
 | 
				
			||||||
 | 
					  val en   = Bool('input);
 | 
				
			||||||
 | 
					  val data = Bits(64, 'output);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ioWritePort extends Bundle()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  val addr = UFix(5, 'input);
 | 
				
			||||||
 | 
					  val en   = Bool('input);
 | 
				
			||||||
 | 
					  val data = Bits(64, 'input);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ioRegfile extends Bundle()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  val r0 = new ioReadPort();
 | 
				
			||||||
 | 
					  val r1 = new ioReadPort();
 | 
				
			||||||
 | 
					  val w0 = new ioWritePort();
 | 
				
			||||||
 | 
					  val w1 = new ioWritePort();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class rocketDpathRegfile extends Component
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  override val io = new ioRegfile();
 | 
				
			||||||
 | 
					  val regfile = Mem(32, io.w0.en && (io.w0.addr != UFix(0,5)), io.w0.addr, io.w0.data);  
 | 
				
			||||||
 | 
					  regfile.write(io.w1.en && (io.w1.addr != UFix(0,5)), io.w1.addr, io.w1.data); 
 | 
				
			||||||
 | 
					  io.r0.data := Mux((io.r0.addr === UFix(0, 5)) || !io.r0.en, Bits(0, 64), regfile(io.r0.addr));
 | 
				
			||||||
 | 
					  io.r1.data := Mux((io.r1.addr === UFix(0, 5)) || !io.r1.en, Bits(0, 64), regfile(io.r1.addr));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										120
									
								
								rocket/src/main/scala/icache.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								rocket/src/main/scala/icache.scala
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,120 @@
 | 
				
			|||||||
 | 
					package Top {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import Chisel._
 | 
				
			||||||
 | 
					import Node._;
 | 
				
			||||||
 | 
					import scala.math._;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// interface between I$ and processor (32 bits wide)
 | 
				
			||||||
 | 
					class ioImem(view: List[String] = null) extends Bundle (view)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  val req_addr  = UFix(32, 'input);
 | 
				
			||||||
 | 
					  val req_val   = Bool('input);
 | 
				
			||||||
 | 
					  val req_rdy   = Bool('output);
 | 
				
			||||||
 | 
					  val resp_data = Bits(32, 'output);
 | 
				
			||||||
 | 
					  val resp_val  = Bool('output);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// interface between I$ and memory (128 bits wide)
 | 
				
			||||||
 | 
					class ioIcache(view: List[String] = null) extends Bundle (view)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  val req_addr  = UFix(32, 'input);
 | 
				
			||||||
 | 
					  val req_val   = Bool('input);
 | 
				
			||||||
 | 
					  val req_rdy   = Bool('output);
 | 
				
			||||||
 | 
					  val resp_data = Bits(128, 'output);
 | 
				
			||||||
 | 
					  val resp_val  = Bool('output);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ioICacheDM extends Bundle() {
 | 
				
			||||||
 | 
					  val cpu = new ioImem();
 | 
				
			||||||
 | 
					  val mem = new ioIcache().flip();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// basic direct mapped instruction cache
 | 
				
			||||||
 | 
					// parameters :
 | 
				
			||||||
 | 
					//    lines = # cache lines
 | 
				
			||||||
 | 
					//    addr_bits = address width (word addressable) bits
 | 
				
			||||||
 | 
					//    32 bit wide cpu port, 128 bit wide memory port, 64 byte cachelines
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class rocketICacheDM(lines: Int, addrbits : Int) extends Component {
 | 
				
			||||||
 | 
					  val io = new ioICacheDM();
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  val indexbits = ceil(log10(lines)/log10(2)).toInt;
 | 
				
			||||||
 | 
					  val offsetbits = 6;
 | 
				
			||||||
 | 
					  val tagmsb    = addrbits - 1;
 | 
				
			||||||
 | 
					  val taglsb    = indexbits+offsetbits;
 | 
				
			||||||
 | 
					  val indexmsb  = taglsb-1;
 | 
				
			||||||
 | 
					  val indexlsb  = offsetbits;
 | 
				
			||||||
 | 
					  val offsetmsb = indexlsb-1;
 | 
				
			||||||
 | 
					  val offsetlsb = 2;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  val s_reset :: s_ready :: s_request :: s_refill_wait :: s_refill :: s_resolve_miss :: Nil = Enum(6) { UFix() };
 | 
				
			||||||
 | 
					  val state = Reg(resetVal = s_reset);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  val r_cpu_req_addr = Reg(Bits(0, addrbits));
 | 
				
			||||||
 | 
					  when (io.cpu.req_val && ((state === s_ready) || (state === s_resolve_miss))) { r_cpu_req_addr <== io.cpu.req_addr; }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  val r_cpu_req_val = Reg(Bool(false));
 | 
				
			||||||
 | 
					  when ((state === s_ready) || (state === s_resolve_miss)) { r_cpu_req_val <== io.cpu.req_val; }
 | 
				
			||||||
 | 
					  otherwise { r_cpu_req_val <== Bool(false); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val refill_count = Reg(resetVal = UFix(0,2));
 | 
				
			||||||
 | 
					  when (io.mem.resp_val) { refill_count <== refill_count + UFix(1); }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  // tag array
 | 
				
			||||||
 | 
					  val tag_wdata = r_cpu_req_addr(tagmsb, taglsb);
 | 
				
			||||||
 | 
					  val tag_waddr = r_cpu_req_addr(indexmsb, indexlsb).toUFix;
 | 
				
			||||||
 | 
					  val tag_we    = (state === s_refill_wait) && io.mem.resp_val;
 | 
				
			||||||
 | 
					  val tag_array = Mem(lines, tag_we, tag_waddr, tag_wdata);
 | 
				
			||||||
 | 
					  val tag_raddr = io.cpu.req_addr(indexmsb, indexlsb);;
 | 
				
			||||||
 | 
					  val tag_lookup = Reg(tag_array.read(tag_raddr));
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  // valid bit array
 | 
				
			||||||
 | 
					  val vb_array = Reg(resetVal = Bits(0, lines));
 | 
				
			||||||
 | 
					  val vb_rdata = Reg(vb_array(io.cpu.req_addr(indexmsb, indexlsb)));
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  when ((state === s_refill_wait) && io.mem.resp_val) { vb_array <== vb_array.bitSet(r_cpu_req_addr(indexmsb, indexlsb).toUFix, UFix(1,1)); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val tag_match = vb_rdata.toBool && (tag_lookup === r_cpu_req_addr(tagmsb, taglsb));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // data array
 | 
				
			||||||
 | 
					  val data_array_waddr = Cat(r_cpu_req_addr(indexmsb, indexlsb), refill_count).toUFix;
 | 
				
			||||||
 | 
					  val data_array = Mem(lines*4, io.mem.resp_val, data_array_waddr, io.mem.resp_data);
 | 
				
			||||||
 | 
					  val data_array_raddr = Cat(io.cpu.req_addr(indexmsb, indexlsb), io.cpu.req_addr(offsetmsb, offsetmsb-1));
 | 
				
			||||||
 | 
					  val data_array_read  = data_array(data_array_raddr);
 | 
				
			||||||
 | 
					  val data_array_rdata = Reg(data_array_read);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  io.cpu.resp_val := (r_cpu_req_val && tag_match && (state === s_ready)); //  || (state === s_resolve_miss);
 | 
				
			||||||
 | 
					  io.cpu.req_rdy  := ((state === s_ready) && (!r_cpu_req_val || (r_cpu_req_val && tag_match))); // || (state === s_resolve_miss);
 | 
				
			||||||
 | 
					  io.cpu.resp_data := MuxLookup(r_cpu_req_addr(offsetmsb-2, offsetlsb).toUFix, data_array_rdata(127, 96), 
 | 
				
			||||||
 | 
					                                Array(UFix(2) -> data_array_rdata(95,64),
 | 
				
			||||||
 | 
					                                      UFix(1) -> data_array_rdata(63,32),
 | 
				
			||||||
 | 
					                                      UFix(0) -> data_array_rdata(31,0)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  io.mem.req_val := (state === s_request);
 | 
				
			||||||
 | 
					  io.mem.req_addr := Cat(r_cpu_req_addr(tagmsb, indexlsb), Bits(0,2)).toUFix;  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // control state machine
 | 
				
			||||||
 | 
					  switch (state) {
 | 
				
			||||||
 | 
					    is (s_reset) {
 | 
				
			||||||
 | 
					      state <== s_ready;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    is (s_ready) {
 | 
				
			||||||
 | 
					      when (r_cpu_req_val && !tag_match) { state <== s_request; }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    is (s_request)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      when (io.mem.req_rdy) { state <== s_refill_wait; }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    is (s_refill_wait) {
 | 
				
			||||||
 | 
					      when (io.mem.resp_val)  { state <== s_refill; }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    is (s_refill) {
 | 
				
			||||||
 | 
					      when (io.mem.resp_val && (refill_count === UFix(3,2))) { state <== s_resolve_miss; }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    is (s_resolve_miss) {
 | 
				
			||||||
 | 
					      state <== s_ready;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }  
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										91
									
								
								rocket/src/main/scala/icache_prefetch.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								rocket/src/main/scala/icache_prefetch.scala
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,91 @@
 | 
				
			|||||||
 | 
					package Top {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import Chisel._;
 | 
				
			||||||
 | 
					import Node._;
 | 
				
			||||||
 | 
					import queues._;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ioIPrefetcherMem(view: List[String] = null) extends Bundle (view)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  val req_addr  = UFix(32, 'output);
 | 
				
			||||||
 | 
					  val req_val   = Bool('output);
 | 
				
			||||||
 | 
					  val req_rdy   = Bool('input);
 | 
				
			||||||
 | 
					  val req_tag   = Bits(3, 'output);
 | 
				
			||||||
 | 
					  val resp_data = Bits(128, 'input);
 | 
				
			||||||
 | 
					  val resp_val  = Bool('input);
 | 
				
			||||||
 | 
					  val resp_tag  = Bits(3, 'input);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ioIPrefetcher extends Bundle() {
 | 
				
			||||||
 | 
					  val icache = new ioIcache();
 | 
				
			||||||
 | 
					  val mem = new ioIPrefetcherMem();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class rocketIPrefetcher extends Component() {
 | 
				
			||||||
 | 
					  val io = new ioIPrefetcher();
 | 
				
			||||||
 | 
					  val pdq = new queueSimplePF(128, 4, 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val s_invalid :: s_valid :: s_refilling :: s_req_wait :: s_resp_wait :: s_bad_resp_wait :: Nil = Enum(6) { UFix() };
 | 
				
			||||||
 | 
					  val state = Reg(resetVal = s_invalid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val demand_miss = io.icache.req_val & io.icache.req_rdy;
 | 
				
			||||||
 | 
					  val prefetch_addr = Reg(resetVal = UFix(0,32));
 | 
				
			||||||
 | 
					  when (demand_miss) { prefetch_addr <== io.icache.req_addr + UFix(4); }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  val addr_match = (prefetch_addr === io.icache.req_addr);
 | 
				
			||||||
 | 
					  val hit = (state != s_invalid) & (state != s_req_wait) & addr_match;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  io.icache.req_rdy := io.mem.req_rdy;
 | 
				
			||||||
 | 
					  val ip_mem_req_rdy  = io.mem.req_rdy & ~(io.icache.req_val & ~hit);
 | 
				
			||||||
 | 
					  val ip_mem_resp_val = io.mem.resp_val && io.mem.resp_tag(0).toBool; 
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  io.mem.req_val  := io.icache.req_val & ~hit | (state === s_req_wait);
 | 
				
			||||||
 | 
					  io.mem.req_tag  := !(io.icache.req_val && !hit);
 | 
				
			||||||
 | 
					  io.mem.req_addr := Mux(io.mem.req_tag.toBool, prefetch_addr, io.icache.req_addr);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  val pdq_reset = Reg(resetVal = Bool(true));
 | 
				
			||||||
 | 
					  pdq_reset <== demand_miss & ~hit | (state === s_bad_resp_wait);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  val fill_cnt = Reg(resetVal = UFix(0, 2));
 | 
				
			||||||
 | 
					  when (ip_mem_resp_val.toBool) { fill_cnt <== fill_cnt + UFix(1,1); }
 | 
				
			||||||
 | 
					  val fill_done = (fill_cnt === UFix(3,2)) & ip_mem_resp_val;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  val forward = Reg(resetVal = Bool(false));
 | 
				
			||||||
 | 
					  val forward_cnt = Reg(resetVal = UFix(0, 2));
 | 
				
			||||||
 | 
					  when (forward & pdq.io.deq_val) { forward_cnt <== forward_cnt + UFix(1,1); }
 | 
				
			||||||
 | 
					  val forward_done = (forward_cnt === UFix(3, 2)) & pdq.io.deq_val;
 | 
				
			||||||
 | 
					  forward <== (demand_miss & hit | forward & ~forward_done);  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  io.icache.resp_val  := (io.mem.resp_val && !io.mem.resp_tag.toBool) || (forward && pdq.io.deq_val);
 | 
				
			||||||
 | 
					  io.icache.resp_data := Mux(forward, pdq.io.deq_bits, io.mem.resp_data);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  pdq.io.q_reset  := pdq_reset;
 | 
				
			||||||
 | 
					  pdq.io.enq_bits := io.mem.resp_data;
 | 
				
			||||||
 | 
					  pdq.io.enq_val  := ip_mem_resp_val.toBool;
 | 
				
			||||||
 | 
					  pdq.io.deq_rdy  := forward;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  switch (state) {
 | 
				
			||||||
 | 
					    is (s_invalid) {
 | 
				
			||||||
 | 
					      when (demand_miss) { state <== s_req_wait; }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    is (s_valid) {
 | 
				
			||||||
 | 
					      when (demand_miss | (forward & forward_done)) { state <== s_req_wait; }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    is (s_refilling) {
 | 
				
			||||||
 | 
					      when (demand_miss & ~addr_match & fill_done.toBool) { state <== s_req_wait; }
 | 
				
			||||||
 | 
					      when (demand_miss & ~addr_match) { state <== s_bad_resp_wait; }
 | 
				
			||||||
 | 
					      when (fill_done.toBool) { state <== s_valid; }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    is (s_req_wait) {
 | 
				
			||||||
 | 
					      when (ip_mem_req_rdy) { state <== s_resp_wait; }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    is (s_resp_wait) {
 | 
				
			||||||
 | 
					      when (demand_miss & ~addr_match) { state <== s_bad_resp_wait; }
 | 
				
			||||||
 | 
					      when (ip_mem_resp_val.toBool) { state <== s_refilling; }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    is (s_bad_resp_wait) {
 | 
				
			||||||
 | 
					      when (fill_done.toBool & ip_mem_resp_val.toBool) { state <== s_req_wait; }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										162
									
								
								rocket/src/main/scala/instructions.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								rocket/src/main/scala/instructions.scala
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,162 @@
 | 
				
			|||||||
 | 
					package Top {
 | 
				
			||||||
 | 
					import Chisel._
 | 
				
			||||||
 | 
					import Node._;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					object Instructions
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  val UNIMP = Bits("b00000000000000000000000000000000", 32);
 | 
				
			||||||
 | 
					  val J = Bits("b?????????????????????????_1100111", 32);
 | 
				
			||||||
 | 
					  val JAL = Bits("b?????????????????????????_1101111", 32);
 | 
				
			||||||
 | 
					  val JALR_C = Bits("b?????_?????_????????????_000_1101011", 32);
 | 
				
			||||||
 | 
					  val JALR_R = Bits("b?????_?????_????????????_001_1101011", 32);
 | 
				
			||||||
 | 
					  val JALR_J = Bits("b?????_?????_????????????_010_1101011", 32);
 | 
				
			||||||
 | 
					  val BEQ = Bits("b?????_?????_?????_???????_000_1100011", 32);
 | 
				
			||||||
 | 
					  val BNE = Bits("b?????_?????_?????_???????_001_1100011", 32);
 | 
				
			||||||
 | 
					  val BLT = Bits("b?????_?????_?????_???????_100_1100011", 32);
 | 
				
			||||||
 | 
					  val BGE = Bits("b?????_?????_?????_???????_101_1100011", 32);
 | 
				
			||||||
 | 
					  val BLTU = Bits("b?????_?????_?????_???????_110_1100011", 32);
 | 
				
			||||||
 | 
					  val BGEU = Bits("b?????_?????_?????_???????_111_1100011", 32);
 | 
				
			||||||
 | 
					  val LUI = Bits("b?????_????????????????????_0110111", 32);
 | 
				
			||||||
 | 
					  val ADDI = Bits("b?????_?????_????????????_000_0010011", 32);
 | 
				
			||||||
 | 
					  val SLLI = Bits("b?????_?????_000000_??????_001_0010011", 32);
 | 
				
			||||||
 | 
					  val SLTI = Bits("b?????_?????_????????????_010_0010011", 32);
 | 
				
			||||||
 | 
					  val SLTIU = Bits("b?????_?????_????????????_011_0010011", 32);
 | 
				
			||||||
 | 
					  val XORI = Bits("b?????_?????_????????????_100_0010011", 32);
 | 
				
			||||||
 | 
					  val SRLI = Bits("b?????_?????_000000_??????_101_0010011", 32);
 | 
				
			||||||
 | 
					  val SRAI = Bits("b?????_?????_000001_??????_101_0010011", 32);
 | 
				
			||||||
 | 
					  val ORI = Bits("b?????_?????_????????????_110_0010011", 32);
 | 
				
			||||||
 | 
					  val ANDI = Bits("b?????_?????_????????????_111_0010011", 32);
 | 
				
			||||||
 | 
					  val ADD = Bits("b?????_?????_?????_0000000000_0110011", 32);
 | 
				
			||||||
 | 
					  val SUB = Bits("b?????_?????_?????_1000000000_0110011", 32);
 | 
				
			||||||
 | 
					  val SLL = Bits("b?????_?????_?????_0000000001_0110011", 32);
 | 
				
			||||||
 | 
					  val SLT = Bits("b?????_?????_?????_0000000010_0110011", 32);
 | 
				
			||||||
 | 
					  val SLTU = Bits("b?????_?????_?????_0000000011_0110011", 32);
 | 
				
			||||||
 | 
					  val riscvXOR = Bits("b?????_?????_?????_0000000100_0110011", 32);
 | 
				
			||||||
 | 
					  val SRL = Bits("b?????_?????_?????_0000000101_0110011", 32);
 | 
				
			||||||
 | 
					  val SRA = Bits("b?????_?????_?????_1000000101_0110011", 32);
 | 
				
			||||||
 | 
					  val riscvOR = Bits("b?????_?????_?????_0000000110_0110011", 32);
 | 
				
			||||||
 | 
					  val riscvAND = Bits("b?????_?????_?????_0000000111_0110011", 32);
 | 
				
			||||||
 | 
					  val MUL = Bits("b?????_?????_?????_0000001000_0110011", 32);
 | 
				
			||||||
 | 
					  val MULH = Bits("b?????_?????_?????_0000001001_0110011", 32);
 | 
				
			||||||
 | 
					  val MULHSU = Bits("b?????_?????_?????_0000001010_0110011", 32);
 | 
				
			||||||
 | 
					  val MULHU = Bits("b?????_?????_?????_0000001011_0110011", 32);
 | 
				
			||||||
 | 
					  val DIV = Bits("b?????_?????_?????_0000001100_0110011", 32);
 | 
				
			||||||
 | 
					  val DIVU = Bits("b?????_?????_?????_0000001101_0110011", 32);
 | 
				
			||||||
 | 
					  val REM = Bits("b?????_?????_?????_0000001110_0110011", 32);
 | 
				
			||||||
 | 
					  val REMU = Bits("b?????_?????_?????_0000001111_0110011", 32);
 | 
				
			||||||
 | 
					  val ADDIW = Bits("b?????_?????_????????????_000_0011011", 32);
 | 
				
			||||||
 | 
					  val SLLIW = Bits("b?????_?????_000000_0_?????_001_0011011", 32);
 | 
				
			||||||
 | 
					  val SRLIW = Bits("b?????_?????_000000_0_?????_101_0011011", 32);
 | 
				
			||||||
 | 
					  val SRAIW = Bits("b?????_?????_000001_0_?????_101_0011011", 32);
 | 
				
			||||||
 | 
					  val ADDW = Bits("b?????_?????_?????_0000000000_0111011", 32);
 | 
				
			||||||
 | 
					  val SUBW = Bits("b?????_?????_?????_1000000000_0111011", 32);
 | 
				
			||||||
 | 
					  val SLLW = Bits("b?????_?????_?????_0000000001_0111011", 32);
 | 
				
			||||||
 | 
					  val SRLW = Bits("b?????_?????_?????_0000000101_0111011", 32);
 | 
				
			||||||
 | 
					  val SRAW = Bits("b?????_?????_?????_1000000101_0111011", 32);
 | 
				
			||||||
 | 
					  val MULW = Bits("b?????_?????_?????_0000001000_0111011", 32);
 | 
				
			||||||
 | 
					  val DIVW = Bits("b?????_?????_?????_0000001100_0111011", 32);
 | 
				
			||||||
 | 
					  val DIVUW = Bits("b?????_?????_?????_0000001101_0111011", 32);
 | 
				
			||||||
 | 
					  val REMW = Bits("b?????_?????_?????_0000001110_0111011", 32);
 | 
				
			||||||
 | 
					  val REMUW = Bits("b?????_?????_?????_0000001111_0111011", 32);
 | 
				
			||||||
 | 
					  val LB = Bits("b?????_?????_????????????_000_0000011", 32);
 | 
				
			||||||
 | 
					  val LH = Bits("b?????_?????_????????????_001_0000011", 32);
 | 
				
			||||||
 | 
					  val LW = Bits("b?????_?????_????????????_010_0000011", 32);
 | 
				
			||||||
 | 
					  val LD = Bits("b?????_?????_????????????_011_0000011", 32);
 | 
				
			||||||
 | 
					  val LBU = Bits("b?????_?????_????????????_100_0000011", 32);
 | 
				
			||||||
 | 
					  val LHU = Bits("b?????_?????_????????????_101_0000011", 32);
 | 
				
			||||||
 | 
					  val LWU = Bits("b?????_?????_????????????_110_0000011", 32);
 | 
				
			||||||
 | 
					  val SB = Bits("b?????_?????_?????_???????_000_0100011", 32);
 | 
				
			||||||
 | 
					  val SH = Bits("b?????_?????_?????_???????_001_0100011", 32);
 | 
				
			||||||
 | 
					  val SW = Bits("b?????_?????_?????_???????_010_0100011", 32);
 | 
				
			||||||
 | 
					  val SD = Bits("b?????_?????_?????_???????_011_0100011", 32);
 | 
				
			||||||
 | 
					  val AMOADD_W = Bits("b?????_?????_?????_00000_000_10_1000011", 32);
 | 
				
			||||||
 | 
					  val AMOSWAP_W = Bits("b?????_?????_?????_00000_010_10_1000011", 32);
 | 
				
			||||||
 | 
					  val AMOAND_W = Bits("b?????_?????_?????_00000_100_10_1000011", 32);
 | 
				
			||||||
 | 
					  val AMOOR_W = Bits("b?????_?????_?????_00000_110_10_1000011", 32);
 | 
				
			||||||
 | 
					  val AMOMIN_W = Bits("b?????_?????_?????_00001_000_10_1000011", 32);
 | 
				
			||||||
 | 
					  val AMOMAX_W = Bits("b?????_?????_?????_00001_010_10_1000011", 32);
 | 
				
			||||||
 | 
					  val AMOMINU_W = Bits("b?????_?????_?????_00001_100_10_1000011", 32);
 | 
				
			||||||
 | 
					  val AMOMAXU_W = Bits("b?????_?????_?????_00001_110_10_1000011", 32);
 | 
				
			||||||
 | 
					  val AMOADD_D = Bits("b?????_?????_?????_00000_000_11_1000011", 32);
 | 
				
			||||||
 | 
					  val AMOSWAP_D = Bits("b?????_?????_?????_00000_010_11_1000011", 32);
 | 
				
			||||||
 | 
					  val AMOAND_D = Bits("b?????_?????_?????_00000_100_11_1000011", 32);
 | 
				
			||||||
 | 
					  val AMOOR_D = Bits("b?????_?????_?????_00000_110_11_1000011", 32);
 | 
				
			||||||
 | 
					  val AMOMIN_D = Bits("b?????_?????_?????_00001_000_11_1000011", 32);
 | 
				
			||||||
 | 
					  val AMOMAX_D = Bits("b?????_?????_?????_00001_010_11_1000011", 32);
 | 
				
			||||||
 | 
					  val AMOMINU_D = Bits("b?????_?????_?????_00001_100_11_1000011", 32);
 | 
				
			||||||
 | 
					  val AMOMAXU_D = Bits("b?????_?????_?????_00001_110_11_1000011", 32);
 | 
				
			||||||
 | 
					  val FENCE   = Bits("b?????_?????_????????????_010_0101111", 32);
 | 
				
			||||||
 | 
					  val FENCE_I = Bits("b?????_?????_????????????_001_0101111", 32);
 | 
				
			||||||
 | 
					  val RDNPC = Bits("b?????_00000_00000_0000000000_0010111", 32);
 | 
				
			||||||
 | 
					  val SYNCI = Bits("b00000_00000_00000_0000000001_0010111", 32);
 | 
				
			||||||
 | 
					  val SYNC = Bits("b00000_00000_00000_0000000010_0010111", 32);
 | 
				
			||||||
 | 
					  val SYSCALL = Bits("b00000_00000_00000_0000000000_1110111", 32);
 | 
				
			||||||
 | 
					  val BREAK = Bits("b00000_00000_00000_0000000001_1110111", 32);
 | 
				
			||||||
 | 
					  val EI = Bits("b?????_00000_00000_0000000000_1111011", 32);
 | 
				
			||||||
 | 
					  val DI = Bits("b?????_00000_00000_0000000001_1111011", 32);
 | 
				
			||||||
 | 
					  val MFPCR = Bits("b?????_00000_?????_0000000010_1111011", 32);
 | 
				
			||||||
 | 
					  val MTPCR = Bits("b00000_?????_?????_0000000011_1111011", 32);
 | 
				
			||||||
 | 
					  val ERET = Bits("b00000_00000_00000_0000000100_1111011", 32);
 | 
				
			||||||
 | 
					  val FADD_S = Bits("b?????_?????_?????_00000_???_00_1010011", 32);
 | 
				
			||||||
 | 
					  val FSUB_S = Bits("b?????_?????_?????_00001_???_00_1010011", 32);
 | 
				
			||||||
 | 
					  val FMUL_S = Bits("b?????_?????_?????_00010_???_00_1010011", 32);
 | 
				
			||||||
 | 
					  val FDIV_S = Bits("b?????_?????_?????_00011_???_00_1010011", 32);
 | 
				
			||||||
 | 
					  val FSQRT_S = Bits("b?????_?????_00000_00100_???_00_1010011", 32);
 | 
				
			||||||
 | 
					  val FSGNJ_S = Bits("b?????_?????_?????_0010111100_1010011", 32);
 | 
				
			||||||
 | 
					  val FSGNJN_S = Bits("b?????_?????_?????_0011011100_1010011", 32);
 | 
				
			||||||
 | 
					  val FSGNJX_S = Bits("b?????_?????_?????_0011111100_1010011", 32);
 | 
				
			||||||
 | 
					  val FADD_D = Bits("b?????_?????_?????_00000_???_01_1010011", 32);
 | 
				
			||||||
 | 
					  val FSUB_D = Bits("b?????_?????_?????_00001_???_01_1010011", 32);
 | 
				
			||||||
 | 
					  val FMUL_D = Bits("b?????_?????_?????_00010_???_01_1010011", 32);
 | 
				
			||||||
 | 
					  val FDIV_D = Bits("b?????_?????_?????_00011_???_01_1010011", 32);
 | 
				
			||||||
 | 
					  val FSQRT_D = Bits("b?????_?????_00000_00100_???_01_1010011", 32);
 | 
				
			||||||
 | 
					  val FSGNJ_D = Bits("b?????_?????_?????_0010111101_1010011", 32);
 | 
				
			||||||
 | 
					  val FSGNJN_D = Bits("b?????_?????_?????_0011011101_1010011", 32);
 | 
				
			||||||
 | 
					  val FSGNJX_D = Bits("b?????_?????_?????_0011111101_1010011", 32);
 | 
				
			||||||
 | 
					  val FCVT_L_S = Bits("b?????_?????_00000_01000_???_00_1010011", 32);
 | 
				
			||||||
 | 
					  val FCVT_LU_S = Bits("b?????_?????_00000_01001_???_00_1010011", 32);
 | 
				
			||||||
 | 
					  val FCVT_W_S = Bits("b?????_?????_00000_01010_???_00_1010011", 32);
 | 
				
			||||||
 | 
					  val FCVT_WU_S = Bits("b?????_?????_00000_01011_???_00_1010011", 32);
 | 
				
			||||||
 | 
					  val FCVT_L_D = Bits("b?????_?????_00000_01000_???_01_1010011", 32);
 | 
				
			||||||
 | 
					  val FCVT_LU_D = Bits("b?????_?????_00000_01001_???_01_1010011", 32);
 | 
				
			||||||
 | 
					  val FCVT_W_D = Bits("b?????_?????_00000_01010_???_01_1010011", 32);
 | 
				
			||||||
 | 
					  val FCVT_WU_D = Bits("b?????_?????_00000_01011_???_01_1010011", 32);
 | 
				
			||||||
 | 
					  val FCVT_S_L = Bits("b?????_?????_00000_01100_???_00_1010011", 32);
 | 
				
			||||||
 | 
					  val FCVT_S_LU = Bits("b?????_?????_00000_01101_???_00_1010011", 32);
 | 
				
			||||||
 | 
					  val FCVT_S_W = Bits("b?????_?????_00000_01110_???_00_1010011", 32);
 | 
				
			||||||
 | 
					  val FCVT_S_WU = Bits("b?????_?????_00000_01111_???_00_1010011", 32);
 | 
				
			||||||
 | 
					  val FCVT_D_L = Bits("b?????_?????_00000_01100_???_01_1010011", 32);
 | 
				
			||||||
 | 
					  val FCVT_D_LU = Bits("b?????_?????_00000_01101_???_01_1010011", 32);
 | 
				
			||||||
 | 
					  val FCVT_D_W = Bits("b?????_?????_00000_0111011101_1010011", 32);
 | 
				
			||||||
 | 
					  val FCVT_D_WU = Bits("b?????_?????_00000_0111111101_1010011", 32);
 | 
				
			||||||
 | 
					  val FCVT_S_D = Bits("b?????_?????_00000_10001_???_00_1010011", 32);
 | 
				
			||||||
 | 
					  val FCVT_D_S = Bits("b?????_?????_00000_10000_???_01_1010011", 32);
 | 
				
			||||||
 | 
					  val FEQ_S = Bits("b?????_?????_?????_1010111100_1010011", 32);
 | 
				
			||||||
 | 
					  val FLT_S = Bits("b?????_?????_?????_1011011100_1010011", 32);
 | 
				
			||||||
 | 
					  val FLE_S = Bits("b?????_?????_?????_1011111100_1010011", 32);
 | 
				
			||||||
 | 
					  val FEQ_D = Bits("b?????_?????_?????_1010111101_1010011", 32);
 | 
				
			||||||
 | 
					  val FLT_D = Bits("b?????_?????_?????_1011011101_1010011", 32);
 | 
				
			||||||
 | 
					  val FLE_D = Bits("b?????_?????_?????_1011111101_1010011", 32);
 | 
				
			||||||
 | 
					  val MFTX_S = Bits("b?????_00000_?????_1100011100_1010011", 32);
 | 
				
			||||||
 | 
					  val MFTX_D = Bits("b?????_00000_?????_1100011101_1010011", 32);
 | 
				
			||||||
 | 
					  val MFFSR = Bits("b?????_00000_00000_1101111100_1010011", 32);
 | 
				
			||||||
 | 
					  val MXTF_S = Bits("b?????_?????_00000_1110011100_1010011", 32);
 | 
				
			||||||
 | 
					  val MXTF_D = Bits("b?????_?????_00000_1110011101_1010011", 32);
 | 
				
			||||||
 | 
					  val MTFSR = Bits("b00000_?????_00000_1110111100_1010011", 32);
 | 
				
			||||||
 | 
					  val FLW = Bits("b?????_?????_????????????_010_0000111", 32);
 | 
				
			||||||
 | 
					  val FLD = Bits("b?????_?????_????????????_011_0000111", 32);
 | 
				
			||||||
 | 
					  val FSW = Bits("b?????_?????_?????_???????_010_0100111", 32);
 | 
				
			||||||
 | 
					  val FSD = Bits("b?????_?????_?????_???????_011_0100111", 32);
 | 
				
			||||||
 | 
					  val FMADD_S = Bits("b?????_?????_?????_?????_???_00_1000011", 32);
 | 
				
			||||||
 | 
					  val FMSUB_S = Bits("b?????_?????_?????_?????_???_00_1000111", 32);
 | 
				
			||||||
 | 
					  val FNMSUB_S = Bits("b?????_?????_?????_?????_???_00_1001011", 32);
 | 
				
			||||||
 | 
					  val FNMADD_S = Bits("b?????_?????_?????_?????_???_00_1001111", 32);
 | 
				
			||||||
 | 
					  val FMADD_D = Bits("b?????_?????_?????_?????_???_01_1000011", 32);
 | 
				
			||||||
 | 
					  val FMSUB_D = Bits("b?????_?????_?????_?????_???_01_1000111", 32);
 | 
				
			||||||
 | 
					  val FNMSUB_D = Bits("b?????_?????_?????_?????_???_01_1001011", 32);
 | 
				
			||||||
 | 
					  val FNMADD_D = Bits("b?????_?????_?????_?????_???_01_1001111", 32);
 | 
				
			||||||
 | 
					  val NOP = ADDI & Bits("b00000000000000000000001111111111", 32);
 | 
				
			||||||
 | 
					  val CFLUSH = Bits("b00000_00000_00000_0000000101_1111011", 32);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										124
									
								
								rocket/src/main/scala/memory.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								rocket/src/main/scala/memory.scala
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,124 @@
 | 
				
			|||||||
 | 
					package Top
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import Chisel._
 | 
				
			||||||
 | 
					import Node._;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import queues._;
 | 
				
			||||||
 | 
					import Constants._;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ioMemory extends Bundle()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  val mem_mrq_val    = Bool('input);
 | 
				
			||||||
 | 
					  val mem_mrq_cmd    = Bits(4, 'input);
 | 
				
			||||||
 | 
					  val mem_mrq_type   = Bits(3, 'input);
 | 
				
			||||||
 | 
					  val mem_xsdq_rdy   = Bool('output);
 | 
				
			||||||
 | 
					  val mem_xsdq_val   = Bool('input);
 | 
				
			||||||
 | 
					  val mem_mrq_deq    = Bool('output);
 | 
				
			||||||
 | 
					  val dpath_rs2      = Bits(64, 'input);
 | 
				
			||||||
 | 
					  val dpath_waddr    = UFix(5, 'input);
 | 
				
			||||||
 | 
					  val dpath_alu_out  = UFix(64, 'input);
 | 
				
			||||||
 | 
					  val dmem_req_val   = Bool('output);
 | 
				
			||||||
 | 
					  val dmem_req_rdy   = Bool('input);
 | 
				
			||||||
 | 
					  val dmem_req_op    = Bits(4, 'output);
 | 
				
			||||||
 | 
					  val dmem_req_addr  = UFix(32, 'output);
 | 
				
			||||||
 | 
					  val dmem_req_data  = Bits(64, 'output);
 | 
				
			||||||
 | 
					  val dmem_req_wmask = Bits(8, 'output);
 | 
				
			||||||
 | 
					  val dmem_req_tag   = Bits(12, 'output);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class rocketMemory extends Component
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  override val io = new ioMemory();
 | 
				
			||||||
 | 
					  val mrq_enq_xf
 | 
				
			||||||
 | 
					    = (io.mem_mrq_cmd === M_FRD || io.mem_mrq_cmd === M_FWR);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val mrq_enq_op
 | 
				
			||||||
 | 
					    = Mux(io.mem_mrq_cmd === M_FRD, M_XRD,
 | 
				
			||||||
 | 
					      Mux(io.mem_mrq_cmd === M_FWR, M_XWR,
 | 
				
			||||||
 | 
					          io.mem_mrq_cmd));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val mrq_enq_type = io.mem_mrq_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val mrq  = new queueSimplePF(45, 4, 2);
 | 
				
			||||||
 | 
					  val xsdq = new queueSimplePF(64, 4, 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mrq.io.q_reset  := Bool(false);
 | 
				
			||||||
 | 
					  mrq.io.enq_bits := Cat(mrq_enq_xf,mrq_enq_op,mrq_enq_type,io.dpath_waddr,io.dpath_alu_out(31,0));
 | 
				
			||||||
 | 
					  mrq.io.enq_val  ^^ io.mem_mrq_val;
 | 
				
			||||||
 | 
					  // mrq.io.enq_rdy  <> (); issue logic takes care of this
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val mrq_deq_xf    = Wire(){Bits(width = 1)};
 | 
				
			||||||
 | 
					  val mrq_deq_op    = Wire(){Bits(width = 4)};
 | 
				
			||||||
 | 
					  val mrq_deq_type  = Wire(){Bits(width = 3)};
 | 
				
			||||||
 | 
					  val mrq_deq_waddr = Wire(){Bits(width = 5)};
 | 
				
			||||||
 | 
					  val mrq_deq_addr  = Wire(){Bits(width = 32)};
 | 
				
			||||||
 | 
					  val mrq_deq_bits  = mrq.io.deq_bits;
 | 
				
			||||||
 | 
					  mrq_deq_bits.Match(Array(mrq_deq_xf, mrq_deq_op, mrq_deq_type, mrq_deq_waddr, mrq_deq_addr));
 | 
				
			||||||
 | 
					  val mrq_deq_val   = mrq.io.deq_val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  xsdq.io.q_reset := Bool(false);
 | 
				
			||||||
 | 
					  xsdq.io.enq_bits ^^ io.dpath_rs2;
 | 
				
			||||||
 | 
					  xsdq.io.enq_val  ^^ io.mem_xsdq_val;
 | 
				
			||||||
 | 
					  xsdq.io.enq_rdy  ^^ io.mem_xsdq_rdy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val mrq_deq_flush = mrq_deq_op === M_FLA;
 | 
				
			||||||
 | 
					  val mrq_deq_load  = mrq_deq_op === M_XRD;
 | 
				
			||||||
 | 
					  val mrq_deq_xstore = mrq_deq_op === M_XWR & ~mrq_deq_xf & xsdq.io.deq_val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val mrq_deq_rdy = io.dmem_req_rdy & (mrq_deq_load | mrq_deq_xstore | mrq_deq_flush);
 | 
				
			||||||
 | 
					  io.mem_mrq_deq := (mrq_deq_val & mrq_deq_rdy).toBool;
 | 
				
			||||||
 | 
					  mrq.io.deq_rdy  := mrq_deq_rdy.toBool;
 | 
				
			||||||
 | 
					  val xsdq_deq_rdy = io.dmem_req_rdy & mrq_deq_val & mrq_deq_op === M_XWR & ~mrq_deq_xf;
 | 
				
			||||||
 | 
					  xsdq.io.deq_rdy  := xsdq_deq_rdy.toBool;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val wdata = xsdq.io.deq_bits;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val wmask_b =
 | 
				
			||||||
 | 
					    Mux(mrq_deq_addr(2,0) === UFix(0, 3), Bits("b0000_0001", 8),
 | 
				
			||||||
 | 
					    Mux(mrq_deq_addr(2,0) === UFix(1, 3), Bits("b0000_0010", 8),
 | 
				
			||||||
 | 
					    Mux(mrq_deq_addr(2,0) === UFix(2, 3), Bits("b0000_0100", 8),
 | 
				
			||||||
 | 
					    Mux(mrq_deq_addr(2,0) === UFix(3, 3), Bits("b0000_1000", 8),
 | 
				
			||||||
 | 
					    Mux(mrq_deq_addr(2,0) === UFix(4, 3), Bits("b0001_0000", 8),
 | 
				
			||||||
 | 
					    Mux(mrq_deq_addr(2,0) === UFix(5, 3), Bits("b0010_0000", 8),
 | 
				
			||||||
 | 
					    Mux(mrq_deq_addr(2,0) === UFix(6, 3), Bits("b0100_0000", 8),
 | 
				
			||||||
 | 
					    Mux(mrq_deq_addr(2,0) === UFix(7, 3), Bits("b1000_0000", 8),
 | 
				
			||||||
 | 
					        UFix(0, 8)))))))));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val wmask_h =
 | 
				
			||||||
 | 
					    Mux(mrq_deq_addr(2,1) === UFix(0, 2), Bits("b0000_0011", 8),
 | 
				
			||||||
 | 
					    Mux(mrq_deq_addr(2,1) === UFix(1, 2), Bits("b0000_1100", 8),
 | 
				
			||||||
 | 
					    Mux(mrq_deq_addr(2,1) === UFix(2, 2), Bits("b0011_0000", 8),
 | 
				
			||||||
 | 
					    Mux(mrq_deq_addr(2,1) === UFix(3, 2), Bits("b1100_0000", 8),
 | 
				
			||||||
 | 
					        UFix(0, 8)))));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val wmask_w =
 | 
				
			||||||
 | 
					    Mux(mrq_deq_addr(2) === UFix(0, 1), Bits("b0000_1111", 8),
 | 
				
			||||||
 | 
					    Mux(mrq_deq_addr(2) === UFix(1, 1), Bits("b1111_0000", 8),
 | 
				
			||||||
 | 
					        UFix(0, 8)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val wmask_d =
 | 
				
			||||||
 | 
					    Bits("b1111_1111", 8);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  io.dmem_req_val  := (mrq_deq_val & (mrq_deq_load | mrq_deq_xstore | mrq_deq_flush)).toBool;
 | 
				
			||||||
 | 
					  io.dmem_req_op   := mrq_deq_op;
 | 
				
			||||||
 | 
					  io.dmem_req_addr := Cat(mrq_deq_addr(31,3), UFix(0, 3)).toUFix;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 io.dmem_req_data :=
 | 
				
			||||||
 | 
					   Mux(mrq_deq_type === MT_B, Fill(8, wdata( 7,0)),
 | 
				
			||||||
 | 
					   Mux(mrq_deq_type === MT_H, Fill(4, wdata(15,0)),
 | 
				
			||||||
 | 
					   Mux(mrq_deq_type === MT_W, Fill(2, wdata(31,0)),
 | 
				
			||||||
 | 
					   Mux(mrq_deq_type === MT_D, wdata,
 | 
				
			||||||
 | 
					       UFix(0, 64)))));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  io.dmem_req_wmask :=
 | 
				
			||||||
 | 
					    Mux(mrq_deq_type === MT_B, wmask_b,
 | 
				
			||||||
 | 
					    Mux(mrq_deq_type === MT_H, wmask_h,
 | 
				
			||||||
 | 
					    Mux(mrq_deq_type === MT_W, wmask_w,
 | 
				
			||||||
 | 
					    Mux(mrq_deq_type === MT_D, wmask_d,
 | 
				
			||||||
 | 
					        UFix(0, 8)))));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  io.dmem_req_tag := Cat(mrq_deq_xf,mrq_deq_type,mrq_deq_addr(2,0),mrq_deq_waddr);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										61
									
								
								rocket/src/main/scala/multiplier.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								rocket/src/main/scala/multiplier.scala
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
				
			|||||||
 | 
					package Top {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import Chisel._
 | 
				
			||||||
 | 
					import Node._;
 | 
				
			||||||
 | 
					import Constants._;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ioMultiplier(width: Int) extends Bundle {
 | 
				
			||||||
 | 
					  // requests
 | 
				
			||||||
 | 
					  val mul_val = Bool('input);
 | 
				
			||||||
 | 
					  val mul_fn  = UFix(3, 'input);
 | 
				
			||||||
 | 
					  val mul_tag = UFix(5, 'input);
 | 
				
			||||||
 | 
					  val in0     = Bits(width, 'input);
 | 
				
			||||||
 | 
					  val in1     = Bits(width, 'input);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  // responses
 | 
				
			||||||
 | 
					  val result     = Bits(width, 'output);
 | 
				
			||||||
 | 
					  val result_tag = UFix(5, 'output);
 | 
				
			||||||
 | 
					  val result_val = Bool('output);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class rocketMultiplier extends Component {
 | 
				
			||||||
 | 
					  val io = new ioMultiplier(64);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  val r_val = Reg(resetVal = Bool(false));
 | 
				
			||||||
 | 
					  val r_fn  = Reg(resetVal = UFix(0,3));
 | 
				
			||||||
 | 
					  val r_tag = Reg(resetVal = UFix(0,5));
 | 
				
			||||||
 | 
					  val r_in0 = Reg(resetVal = Bits(0,64));
 | 
				
			||||||
 | 
					  val r_in1 = Reg(resetVal = Bits(0,64));
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  r_val <== io.mul_val;
 | 
				
			||||||
 | 
					  when (io.mul_val) {
 | 
				
			||||||
 | 
					    r_fn  <== io.mul_fn;
 | 
				
			||||||
 | 
					    r_tag <== io.mul_tag;
 | 
				
			||||||
 | 
					    r_in0 <== io.in0;
 | 
				
			||||||
 | 
					    r_in1 <== io.in1;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  val sxl64 = (r_fn === MUL_64H) || (r_fn === MUL_64HSU);
 | 
				
			||||||
 | 
					  val sxr64 = (r_fn === MUL_64H);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val lhs = Cat(r_in0(63) & sxl64, r_in0);
 | 
				
			||||||
 | 
					  val rhs = Cat(r_in1(63) & sxr64, r_in1);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  val mul_result = lhs.toFix * rhs.toFix;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  val mul_output = MuxCase(mul_result(63,0), Array(
 | 
				
			||||||
 | 
					    ((r_fn === MUL_64H) || (r_fn === MUL_64HU) || (r_fn === MUL_64HSU)) -> mul_result(127,64),
 | 
				
			||||||
 | 
					    (r_fn === MUL_32) -> Cat(Fill(32, mul_result(31)), mul_result(31, 0))));
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  // just a hack for now, this should be a parameterized number of stages
 | 
				
			||||||
 | 
					  val r_result     = Reg(Reg(Reg(mul_output)));
 | 
				
			||||||
 | 
					  val r_result_tag = Reg(Reg(Reg(r_tag))); 
 | 
				
			||||||
 | 
					  val r_result_val = Reg(Reg(Reg(r_val)));
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  io.result := r_result;
 | 
				
			||||||
 | 
					  io.result_tag := r_result_tag;
 | 
				
			||||||
 | 
					  io.result_val := r_result_val;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										225
									
								
								rocket/src/main/scala/queues.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										225
									
								
								rocket/src/main/scala/queues.scala
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,225 @@
 | 
				
			|||||||
 | 
					package queues
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import Chisel._
 | 
				
			||||||
 | 
					import Node._;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ioQueueCtrl(addr_sz: Int) extends Bundle()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  val q_reset = Bool('input);
 | 
				
			||||||
 | 
					  val enq_val = Bool('input);
 | 
				
			||||||
 | 
					  val enq_rdy = Bool('output);
 | 
				
			||||||
 | 
					  val deq_val = Bool('output);
 | 
				
			||||||
 | 
					  val deq_rdy = Bool('input);
 | 
				
			||||||
 | 
					  val wen     = Bool('output);
 | 
				
			||||||
 | 
					  val waddr   = UFix(addr_sz, 'output);
 | 
				
			||||||
 | 
					  val raddr   = UFix(addr_sz, 'output);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class queueCtrl(entries: Int, addr_sz: Int) extends Component
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  override val io = new ioQueueCtrl(addr_sz);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Enqueue and dequeue pointers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val enq_ptr = Reg(width = addr_sz, resetVal = UFix(0, addr_sz));
 | 
				
			||||||
 | 
					  val deq_ptr = Reg(width = addr_sz, resetVal = UFix(0, addr_sz));
 | 
				
			||||||
 | 
					  val full    = Reg(width = 1, resetVal = Bool(false));
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  when (io.q_reset) {
 | 
				
			||||||
 | 
					    enq_ptr <== UFix(0, addr_sz);
 | 
				
			||||||
 | 
					    deq_ptr <== UFix(0, addr_sz);
 | 
				
			||||||
 | 
					    full <== Bool(false);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  io.waddr := enq_ptr;
 | 
				
			||||||
 | 
					  io.raddr := deq_ptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // We enq/deq only when they are both ready and valid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val do_enq = io.enq_rdy && io.enq_val;
 | 
				
			||||||
 | 
					  val do_deq = io.deq_rdy && io.deq_val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Determine if we have pipeline or flowthrough behaviour and
 | 
				
			||||||
 | 
					  // set the write enable accordingly.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val empty = ~full && (enq_ptr === deq_ptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  io.wen := do_enq;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Ready signals are calculated from full register. If pipeline
 | 
				
			||||||
 | 
					  // behavior is enabled, then the enq_rdy signal is also calculated
 | 
				
			||||||
 | 
					  // combinationally from the deq_rdy signal. If flowthrough behavior
 | 
				
			||||||
 | 
					  // is enabled then the deq_val signal is also calculated combinationally
 | 
				
			||||||
 | 
					  // from the enq_val signal.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  io.enq_rdy := ~full;
 | 
				
			||||||
 | 
					  io.deq_val := ~empty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Control logic for the enq/deq pointers and full register
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val deq_ptr_inc = deq_ptr + UFix(1, 1);
 | 
				
			||||||
 | 
					  val enq_ptr_inc = enq_ptr + UFix(1, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val deq_ptr_next =
 | 
				
			||||||
 | 
					    Mux(do_deq, deq_ptr_inc,
 | 
				
			||||||
 | 
					        deq_ptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val enq_ptr_next =
 | 
				
			||||||
 | 
					    Mux(do_enq, enq_ptr_inc,
 | 
				
			||||||
 | 
					        enq_ptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val full_next = 
 | 
				
			||||||
 | 
					    Mux(do_enq && ~do_deq && ( enq_ptr_inc === deq_ptr ), Bool(true),
 | 
				
			||||||
 | 
					    Mux(do_deq && full,                                   Bool(false),
 | 
				
			||||||
 | 
					        full));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  enq_ptr <== enq_ptr_next;
 | 
				
			||||||
 | 
					  deq_ptr <== deq_ptr_next;
 | 
				
			||||||
 | 
					  full    <== full_next;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ioQueueSimplePF(data_sz: Int) extends Bundle()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  val q_reset  = Bool('input);
 | 
				
			||||||
 | 
					  val enq_val  = Bool('input);
 | 
				
			||||||
 | 
					  val enq_rdy  = Bool('output);
 | 
				
			||||||
 | 
					  val deq_val  = Bool('output);
 | 
				
			||||||
 | 
					  val deq_rdy  = Bool('input);
 | 
				
			||||||
 | 
					  val enq_bits = Bits(data_sz, 'input);
 | 
				
			||||||
 | 
					  val deq_bits = Bits(data_sz, 'output);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class queueSimplePF(data_sz: Int, entries: Int, addr_sz: Int) extends Component
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  override val io = new ioQueueSimplePF(data_sz);
 | 
				
			||||||
 | 
					  val ctrl = new queueCtrl(entries, addr_sz);
 | 
				
			||||||
 | 
					  ctrl.io.q_reset ^^ io.q_reset;
 | 
				
			||||||
 | 
					  ctrl.io.deq_val ^^ io.deq_val;
 | 
				
			||||||
 | 
					  ctrl.io.enq_rdy ^^ io.enq_rdy;
 | 
				
			||||||
 | 
					  ctrl.io.enq_val ^^ io.enq_val;     
 | 
				
			||||||
 | 
					  ctrl.io.deq_rdy ^^ io.deq_rdy;
 | 
				
			||||||
 | 
					  val ram = Mem(entries, ctrl.io.wen, ctrl.io.waddr, io.enq_bits);
 | 
				
			||||||
 | 
					  io.deq_bits := ram(ctrl.io.raddr);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TODO: SHOULD USE INHERITANCE BUT BREAKS INTROSPECTION CODE
 | 
				
			||||||
 | 
					// class IOqueueCtrlFlow extends IOqueueCtrl 
 | 
				
			||||||
 | 
					class ioQueueCtrlFlow(addr_sz: Int) extends Bundle() /* IOqueueCtrl */
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  val enq_val  = Bool('input);
 | 
				
			||||||
 | 
					  val enq_rdy  = Bool('output);
 | 
				
			||||||
 | 
					  val deq_val  = Bool('output);
 | 
				
			||||||
 | 
					  val deq_rdy  = Bool('input);
 | 
				
			||||||
 | 
					  val wen      = Bool('output);
 | 
				
			||||||
 | 
					  val waddr    = UFix(addr_sz, 'output);
 | 
				
			||||||
 | 
					  val raddr    = UFix(addr_sz, 'output);
 | 
				
			||||||
 | 
					  val flowthru = Bool('output);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class queueCtrlFlow(entries: Int, addr_sz: Int) extends Component
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  override val io = new ioQueueCtrlFlow(addr_sz);
 | 
				
			||||||
 | 
					  // Enqueue and dequeue pointers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val enq_ptr = Reg(width = addr_sz, resetVal = UFix(0, addr_sz));
 | 
				
			||||||
 | 
					  val deq_ptr = Reg(width = addr_sz, resetVal = UFix(0, addr_sz));
 | 
				
			||||||
 | 
					  val full    = Reg(width = 1, resetVal = Bool(false));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  io.waddr := enq_ptr;
 | 
				
			||||||
 | 
					  io.raddr := deq_ptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // We enq/deq only when they are both ready and valid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val do_enq = io.enq_rdy && io.enq_val;
 | 
				
			||||||
 | 
					  val do_deq = io.deq_rdy && io.deq_val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Determine if we have pipeline or flowthrough behaviour and
 | 
				
			||||||
 | 
					  // set the write enable accordingly.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val empty       = ~full && (enq_ptr === deq_ptr);
 | 
				
			||||||
 | 
					  val do_flowthru = empty && do_enq && do_deq;
 | 
				
			||||||
 | 
					  io.flowthru  := do_flowthru;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  io.wen    := do_enq && ~do_flowthru;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Ready signals are calculated from full register. If pipeline
 | 
				
			||||||
 | 
					  // behavior is enabled, then the enq_rdy signal is also calculated
 | 
				
			||||||
 | 
					  // combinationally from the deq_rdy signal. If flowthrough behavior
 | 
				
			||||||
 | 
					  // is enabled then the deq_val signal is also calculated combinationally
 | 
				
			||||||
 | 
					  // from the enq_val signal.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  io.enq_rdy  := ~full;
 | 
				
			||||||
 | 
					  io.deq_val  := ~empty || ( empty && io.enq_val );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Control logic for the enq/deq pointers and full register
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val deq_ptr_inc = deq_ptr + UFix(1, 1);
 | 
				
			||||||
 | 
					  val enq_ptr_inc = enq_ptr + UFix(1, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val deq_ptr_next =
 | 
				
			||||||
 | 
					    Mux(do_deq && ~do_flowthru, deq_ptr_inc,
 | 
				
			||||||
 | 
					        deq_ptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val enq_ptr_next =
 | 
				
			||||||
 | 
					    Mux(do_enq && ~do_flowthru, enq_ptr_inc,
 | 
				
			||||||
 | 
					        enq_ptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val full_next = 
 | 
				
			||||||
 | 
					    Mux(do_enq && ~do_deq && ( enq_ptr_inc === deq_ptr ), Bool(true),
 | 
				
			||||||
 | 
					    Mux(do_deq && full,                                   Bool(false),
 | 
				
			||||||
 | 
					        full));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  enq_ptr <== enq_ptr_next;
 | 
				
			||||||
 | 
					  deq_ptr <== deq_ptr_next;
 | 
				
			||||||
 | 
					  full    <== full_next;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ioQueueDpathFlow(data_sz: Int, addr_sz: Int) extends Bundle()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  val wen         = Bool('input);
 | 
				
			||||||
 | 
					  val flowthru    = Bool('input);
 | 
				
			||||||
 | 
					  val deq_bits    = Bits(data_sz, 'output);
 | 
				
			||||||
 | 
					  val enq_bits    = Bits(data_sz, 'input);
 | 
				
			||||||
 | 
					  val waddr       = UFix(addr_sz, 'input);
 | 
				
			||||||
 | 
					  val raddr       = UFix(addr_sz, 'input);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class queueDpathFlow(data_sz: Int, entries: Int, addr_sz: Int) extends Component
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  override val io = new ioQueueDpathFlow(data_sz, addr_sz);
 | 
				
			||||||
 | 
					  val ram  = Mem(entries, io.wen, io.waddr, io.enq_bits);
 | 
				
			||||||
 | 
					  val rout = ram(io.raddr);
 | 
				
			||||||
 | 
					  io.deq_bits := Mux(io.flowthru, io.enq_bits, rout);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ioQueueFlowPF(data_sz: Int) extends Bundle()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  val enq_val     = Bool('input);
 | 
				
			||||||
 | 
					  val enq_rdy     = Bool('output);
 | 
				
			||||||
 | 
					  val enq_bits    = Bits(data_sz, 'input);
 | 
				
			||||||
 | 
					  val deq_val     = Bool('output);
 | 
				
			||||||
 | 
					  val deq_rdy     = Bool('input);
 | 
				
			||||||
 | 
					  val deq_bits    = Bits(data_sz, 'output);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class queueFlowPF(data_sz: Int, entries: Int, addr_sz: Int) extends Component
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  override val io = new ioQueueFlowPF(data_sz);
 | 
				
			||||||
 | 
					  val ctrl  = new queueCtrlFlow(entries, addr_sz);
 | 
				
			||||||
 | 
					  val dpath = new queueDpathFlow(data_sz, entries, addr_sz);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  ctrl.io.deq_rdy   ^^ io.deq_rdy;
 | 
				
			||||||
 | 
					  ctrl.io.wen       <> dpath.io.wen;
 | 
				
			||||||
 | 
					  ctrl.io.raddr     <> dpath.io.raddr;
 | 
				
			||||||
 | 
					  ctrl.io.waddr     <> dpath.io.waddr;
 | 
				
			||||||
 | 
					  ctrl.io.flowthru  <> dpath.io.flowthru;
 | 
				
			||||||
 | 
					  ctrl.io.enq_val   ^^ io.enq_val;       
 | 
				
			||||||
 | 
					  dpath.io.enq_bits ^^ io.enq_bits;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ctrl.io.deq_val   ^^ io.deq_val;
 | 
				
			||||||
 | 
					  ctrl.io.enq_rdy   ^^ io.enq_rdy;
 | 
				
			||||||
 | 
					  dpath.io.deq_bits ^^ io.deq_bits;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										54
									
								
								rocket/src/main/scala/top.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								rocket/src/main/scala/top.scala
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,54 @@
 | 
				
			|||||||
 | 
					package Top {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import Chisel._
 | 
				
			||||||
 | 
					import Node._;
 | 
				
			||||||
 | 
					import Constants._;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ioTop extends Bundle  {
 | 
				
			||||||
 | 
					  val debug   = new ioDebug();
 | 
				
			||||||
 | 
					  val console = new ioConsole();
 | 
				
			||||||
 | 
					  val host    = new ioHost();
 | 
				
			||||||
 | 
					  val mem     = new ioMem();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Top() extends Component {
 | 
				
			||||||
 | 
					  val io        = new ioTop();
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  val cpu       = new rocketProc();
 | 
				
			||||||
 | 
					  val icache    = new rocketICacheDM(128, 32); // lines, address bits
 | 
				
			||||||
 | 
					  val icache_pf = new rocketIPrefetcher();
 | 
				
			||||||
 | 
					  val dcache    = new rocketDCacheDM_flush(128, 32);
 | 
				
			||||||
 | 
					  val arbiter   = new rocketMemArbiter();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  arbiter.io.mem    ^^ io.mem; 
 | 
				
			||||||
 | 
					  arbiter.io.dcache <> dcache.io.mem;
 | 
				
			||||||
 | 
					  arbiter.io.icache <> icache_pf.io.mem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  cpu.io.host       ^^ io.host;
 | 
				
			||||||
 | 
					  cpu.io.debug      ^^ io.debug;
 | 
				
			||||||
 | 
					  cpu.io.console    ^^ io.console;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  icache.io.mem     <> icache_pf.io.icache;
 | 
				
			||||||
 | 
					  cpu.io.imem       <> icache.io.cpu;
 | 
				
			||||||
 | 
					  cpu.io.dmem       <> dcache.io.cpu;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					object top_main {
 | 
				
			||||||
 | 
					  def main(args: Array[String]) = { 
 | 
				
			||||||
 | 
					    // Can turn off --debug and --vcd when done with debugging to improve emulator performance
 | 
				
			||||||
 | 
					//    val cpu_args = args ++ Array("--target-dir", "generated-src","--debug","--vcd");
 | 
				
			||||||
 | 
					    val cpu_args = args ++ Array("--target-dir", "generated-src","--debug");
 | 
				
			||||||
 | 
					    // Set variables based off of command flags
 | 
				
			||||||
 | 
					//     for(a <- args) {
 | 
				
			||||||
 | 
					//         a match {
 | 
				
			||||||
 | 
					//               case "-bp" => isBranchPrediction = true;
 | 
				
			||||||
 | 
					//               case any =>
 | 
				
			||||||
 | 
					//         }
 | 
				
			||||||
 | 
					//     }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					     chiselMain(cpu_args, () => new Top());
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										56
									
								
								rocket/src/main/scala/writeback.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								rocket/src/main/scala/writeback.scala
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,56 @@
 | 
				
			|||||||
 | 
					package Top
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import Chisel._
 | 
				
			||||||
 | 
					import Node._;
 | 
				
			||||||
 | 
					import Constants._;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ioWriteback extends Bundle()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  val dmem_resp_val     = Bool('input);
 | 
				
			||||||
 | 
					  val dmem_resp_data    = UFix(64, 'input);
 | 
				
			||||||
 | 
					  val dmem_resp_tag     = UFix(12, 'input);
 | 
				
			||||||
 | 
					  val wb_waddr          = UFix(5, 'output);
 | 
				
			||||||
 | 
					  val wb_wen            = Bool('output);
 | 
				
			||||||
 | 
					  val wb_wdata          = Bits(64, 'output);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class rocketWriteback extends Component
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  override val io = new ioWriteback();
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  val r_dmem_resp_val  = Reg(io.dmem_resp_val);
 | 
				
			||||||
 | 
					  val r_dmem_resp_data = Reg(io.dmem_resp_data);
 | 
				
			||||||
 | 
					  val r_dmem_resp_tag  = Reg(io.dmem_resp_tag);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val dmem_resp_xf    = r_dmem_resp_tag(11);
 | 
				
			||||||
 | 
					  val dmem_resp_type  = r_dmem_resp_tag(10, 8);
 | 
				
			||||||
 | 
					  val dmem_resp_pos   = r_dmem_resp_tag(7, 5);
 | 
				
			||||||
 | 
					  val dmem_resp_waddr = r_dmem_resp_tag(4, 0);
 | 
				
			||||||
 | 
					  val dmem_resp_xval  = r_dmem_resp_val & ~dmem_resp_xf;
 | 
				
			||||||
 | 
					  val dmem_resp_fval  = r_dmem_resp_val &  dmem_resp_xf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val dmem_resp_data_w = 
 | 
				
			||||||
 | 
					    Mux(dmem_resp_pos(2).toBool, r_dmem_resp_data(63, 32), r_dmem_resp_data(31, 0));
 | 
				
			||||||
 | 
					  val dmem_resp_data_h = 
 | 
				
			||||||
 | 
					    Mux(dmem_resp_pos(1).toBool, dmem_resp_data_w(31, 16),  dmem_resp_data_w(15, 0));
 | 
				
			||||||
 | 
					  val dmem_resp_data_b = 
 | 
				
			||||||
 | 
					    Mux(dmem_resp_pos(0).toBool, dmem_resp_data_h(15, 8),   dmem_resp_data_h(7, 0));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val dmem_resp_data_final =
 | 
				
			||||||
 | 
					    Mux(dmem_resp_type === MT_B,  Cat(Fill(56, dmem_resp_data_b(7)), dmem_resp_data_b),
 | 
				
			||||||
 | 
					    Mux(dmem_resp_type === MT_BU, Cat(UFix(0, 56), dmem_resp_data_b),
 | 
				
			||||||
 | 
					    Mux(dmem_resp_type === MT_H,  Cat(Fill(48, dmem_resp_data_h(15)), dmem_resp_data_h),
 | 
				
			||||||
 | 
					    Mux(dmem_resp_type === MT_HU, Cat(UFix(0, 48), dmem_resp_data_h),
 | 
				
			||||||
 | 
					    Mux(dmem_resp_type === MT_W,  Cat(Fill(32, dmem_resp_data_w(31)), dmem_resp_data_w),
 | 
				
			||||||
 | 
					    Mux(dmem_resp_type === MT_WU, Cat(UFix(0, 32), dmem_resp_data_w),
 | 
				
			||||||
 | 
					    Mux(dmem_resp_type === MT_D,  r_dmem_resp_data,
 | 
				
			||||||
 | 
					        UFix(0, 64))))))));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  io.wb_wen   := dmem_resp_xval.toBool;
 | 
				
			||||||
 | 
					  io.wb_waddr := dmem_resp_waddr;
 | 
				
			||||||
 | 
					  io.wb_wdata := dmem_resp_data_final;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user