⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpuside.v

📁 这是arm7处理器的verilog全代码
💻 V
📖 第 1 页 / 共 2 页
字号:
		 dedsec = dedsec_bits({cacheline[127:32+16], source[7:0], cacheline[31+ 8:0]}); 	      end	   4'b0110 : 	      begin 		 cacheline[ 32+23: 32+16] = source[ 7: 0]; 		 dedsec = dedsec_bits({cacheline[127:32+24], source[7:0], cacheline[31+16:0]}); 	      end	   4'b0111 : 	      begin 		 cacheline[ 32+31: 32+24] = source[ 7: 0]; 		 dedsec = dedsec_bits({cacheline[127:32+32], source[7:0], cacheline[31+24:0]}); 	      end	   4'b1000 : 	      begin 		 cacheline[ 64+ 7: 64+ 0] = source[ 7: 0]; 		 dedsec = dedsec_bits({cacheline[127:64+ 8], source[7:0], cacheline[63+ 0:0]}); 	      end	   4'b1001 : 	      begin 		 cacheline[ 64+15: 64+ 8] = source[ 7: 0]; 		 dedsec = dedsec_bits({cacheline[127:64+16], source[7:0], cacheline[63+ 8:0]}); 	      end	   4'b1010 : 	      begin 		 cacheline[ 64+23: 64+16] = source[ 7: 0]; 		 dedsec = dedsec_bits({cacheline[127:64+24], source[7:0], cacheline[63+16:0]}); 	      end	   4'b1011 : 	      begin 		 cacheline[ 64+31: 64+24] = source[ 7: 0]; 		 dedsec = dedsec_bits({cacheline[127:64+32], source[7:0], cacheline[63+24:0]}); 	      end	   4'b1100 : 	      begin 		 cacheline[ 96+ 7: 96+ 0] = source[ 7: 0]; 		 dedsec = dedsec_bits({cacheline[127:96+ 8], source[7:0], cacheline[95+ 0:0]}); 	      end	   4'b1101 : 	      begin 		 cacheline[ 96+15: 96+ 8] = source[ 7: 0]; 		 dedsec = dedsec_bits({cacheline[127:96+16], source[7:0], cacheline[95+ 8:0]}); 	      end	   4'b1110 : 	      begin 		 cacheline[ 96+23: 96+16] = source[ 7: 0]; 		 dedsec = dedsec_bits({cacheline[127:96+24], source[7:0], cacheline[95+16:0]}); 	      end	   4'b1111 : 	      begin 		 cacheline[ 96+31: 96+24] = source[ 7: 0]; 		 dedsec = dedsec_bits({                      source[7:0], cacheline[95+24:0]}); 	      end	 endcase // case(address[3:2])      end         endtask // input_byte      // Use word index to output the appropriate word from the cacheline to D   task output_word;      input [127:0] 	     cacheline;      input [1:0] 	     word;            begin	 case (word)	   2'b00 : Dout = cacheline[31:0];	   2'b01 : Dout = cacheline[63:32];	   2'b10 : Dout = cacheline[95:64];	   2'b11 : Dout = cacheline[127:96];	 endcase // case(address[3:2])      end         endtask      // Use bytepos index to output the appropriate byte from the cacheline to D   task output_byte;      input [127:0] 	     cacheline;      input [3:0] 	     bytepos;            begin	 Dout[31:8] = 24'h000000;	 case (bytepos)	   4'b0000 : Dout[7:0] = cacheline[  0+ 7:  0+ 0];	   	   4'b0001 : Dout[7:0] = cacheline[  0+15:  0+ 8];	   	   4'b0010 : Dout[7:0] = cacheline[  0+23:  0+16];	   	   4'b0011 : Dout[7:0] = cacheline[  0+31:  0+24];	   	   4'b0100 : Dout[7:0] = cacheline[ 32+ 7: 32+ 0];	   	   4'b0101 : Dout[7:0] = cacheline[ 32+15: 32+ 8];	   	   4'b0110 : Dout[7:0] = cacheline[ 32+23: 32+16];	   	   4'b0111 : Dout[7:0] = cacheline[ 32+31: 32+24];	   	   4'b1000 : Dout[7:0] = cacheline[ 64+ 7: 64+ 0];	   	   4'b1001 : Dout[7:0] = cacheline[ 64+15: 64+ 8];	   	   4'b1010 : Dout[7:0] = cacheline[ 64+23: 64+16];	   	   4'b1011 : Dout[7:0] = cacheline[ 64+31: 64+24];	   	   4'b1100 : Dout[7:0] = cacheline[ 96+ 7: 96+ 0];	   	   4'b1101 : Dout[7:0] = cacheline[ 96+15: 96+ 8];	   	   4'b1110 : Dout[7:0] = cacheline[ 96+23: 96+16];	   	   4'b1111 : Dout[7:0] = cacheline[ 96+31: 96+24];	   	 endcase // case(address[3:2])      end         endtask      // Displace to victim cache   task move_main_to_victim;      input [31:0] 	     address;   // NB. Only upper bits of address are used                                        //  (for working out the cache line)      begin	 `ifdef TALK	    $display("CPUside: Moving cache line b%b = d%d (address %h) to victim cache", 		     main_cache_line(address), main_cache_line(address), address);	 `endif	 victim_cache[oldest_victim_line] <= @(posedge sysclk) 	    main_cache[main_cache_line(address)];	 // The victim tag is the main tag && offset	 victim_cache_tag[oldest_victim_line] <= @(posedge sysclk) 	    { main_cache_tag[main_cache_line(address)], main_cache_line(address) };	 	 victim_cache_dedsec[oldest_victim_line] <= @(posedge sysclk) 	    main_cache_dedsec[main_cache_line(address)];	 	 victim_cache_valid[oldest_victim_line] <= @(posedge sysclk) 	    main_cache_valid[main_cache_line(address)];	 // Move our FIFO onwards	 oldest_victim_line <= @(posedge sysclk) oldest_victim_line + 1;      end         endtask      // Swap lines in the two caches   task swap_caches;      input [31:0] 	     address;      begin	 victim_cache_tag[victim_cache_line(address)] <= @(posedge sysclk) 	    { main_cache_tag[main_cache_line(address)], main_cache_line(address) };	 	 victim_cache[victim_cache_line(address)] <= @(posedge sysclk) 	    main_cache[main_cache_line(address)];	 	 victim_cache_dedsec[victim_cache_line(address)] <= @(posedge sysclk) 	    main_cache_dedsec[main_cache_line(address)];	 	 main_cache_tag[main_cache_line(address)] <= @(posedge sysclk) 	    A[31:32-`MAIN_CACHE_TAG_BITS]; // *********** Check this line *************************	 	 main_cache[main_cache_line(address)] <= @(posedge sysclk) 	    victim_cache[victim_cache_line(address)];	 	 main_cache_dedsec[main_cache_line(address)] <= @(posedge sysclk) 	    victim_cache_dedsec[victim_cache_line(address)];      end   endtask       // Returns the bits used for indexing the main cache from the given address   function [`MAIN_CACHE_LINE_BITS-1:0] main_cache_line;      input [31:0] 	     address;            main_cache_line = address[`MAIN_CACHE_LINE_BIT_HIGH:`MAIN_CACHE_LINE_BIT_LOW];   endfunction      // Returns the bits used for indexing the victim cache from the given address   function [27:0] victim_cache_line;      input [31:0] 	     address;            if (victim_cache_tag[0] == address[31:4])	 victim_cache_line = 0;      else if (victim_cache_tag[1] == address[31:4])	 victim_cache_line = 1;      else if (victim_cache_tag[2] == address[31:4])	 victim_cache_line = 2;      else //if (victim_cache_tag[3] == address[31:4])	 victim_cache_line = 3;   endfunction      // Returns whether the given address has a match in the main cache   function in_main_cache;      input [31:0] 	     address;      in_main_cache = ( main_cache_tag[main_cache_line(address)] == 			  address[`MAIN_CACHE_TAG_BIT_HIGH:`MAIN_CACHE_TAG_BIT_LOW]			& main_cache_valid[main_cache_line(address)]			& main_dedsec_result );   endfunction      // Returns whether the given address has a match in the victim cache   function in_victim_cache;      input [31:0] 	     address;            in_victim_cache = ( ( ( (  victim_cache_tag[0] == address[31:4]) & victim_cache_valid[0] )			    | ( (victim_cache_tag[1] == address[31:4]) & victim_cache_valid[1] )			    | ( (victim_cache_tag[2] == address[31:4]) & victim_cache_valid[2] )			    | ( (victim_cache_tag[3] == address[31:4]) & victim_cache_valid[3] ) )			  & victim_dedsec_result );   endfunction // in_victim_cache      // nWAIT assignment   assign nWAIT = !cpu_busy;   // D assignment   assign D = Dout;      // Initial setup   initial            begin	 present_cpu_state = `CPUSIDE_IDLE;	 for (i = 0; i < `MAIN_CACHE_LINES; i = i+1)	    main_cache_valid[i] = 0;	 for (i = 0; i < `VICTIM_CACHE_LINES; i = i+1)	    victim_cache_valid[i] = 0;	 oldest_victim_line = 0;      end    // Correct DEDSEC errors as they occur - main cache   always      begin	 @(posedge sysclk) #1;	 pass_dedsec(main_cache[main_cache_line(A)],		     main_cache_dedsec[main_cache_line(A)],		     main_dedsec_result );      end // always begin      // Correct DEDSEC errors as they occur - victim cache   always      begin	 @(posedge sysclk) #1;	 pass_dedsec(victim_cache[victim_cache_line(A)],		     victim_cache_dedsec[victim_cache_line(A)],		     victim_dedsec_result );      end // always begin      // CPU ASM   always      begin	 @(posedge sysclk) enter_new_cpu_state(`CPUSIDE_IDLE);	 cpu_busy = 0;	 if (! nMREQ)	    if (nRW)  // Write / Store	       begin		  while (st_busy)		     begin			cpu_busy = 1;			@(posedge sysclk) enter_new_cpu_state(`CPUSIDE_WAIT);		     end // while (st_busy)		  		  if (in_main_cache(A))		     if (MAS[1])			input_word(main_cache[main_cache_line(A)], 				   A[3:2], 				   D, 				   main_cache_dedsec[main_cache_line(A)]);		     else			input_byte(main_cache[main_cache_line(A)], 				   A[3:0], 				   D, 				   main_cache_dedsec[main_cache_line(A)]);		  else		     if (in_victim_cache(A))			begin			   if (MAS[1])			      input_word(victim_cache[victim_cache_line(A)], 					 A[3:2], 					 D, 					 victim_cache_dedsec[victim_cache_line(A)]);			   else			      input_byte(victim_cache[victim_cache_line(A)],					 A[3:0], 					 D, 					 victim_cache_dedsec[victim_cache_line(A)]);			end // if (in_victim_cache(A))		  if (MAS[1])		     begin			// Memoryside needs this in a register			write_buffer_data <= @(posedge sysclk) D;		     end		  else		     begin			// Memoryside needs this in a register			write_buffer_data <= @(posedge sysclk) {D[7:0], D[7:0], D[7:0], D[7:0]};		     end // else: !if(MAS[1])		  // Memoryside needs this in a register		  write_buffer_is_byte <= @(posedge sysclk) ! MAS[1];		  // Memoryside needs the address in this clock cycle		  write_buffer_addr = A;		  Store_Trigger = 1;	       end	    else	       begin // (!nRW) = Read / Load		  `ifdef TALK		     $display("CPUside: Load start");		  `endif		     if (in_main_cache(A))			begin			`ifdef TALK			   $display("CPUside: Main cache hit");			`endif			   if (MAS[1])			      output_word(main_cache[main_cache_line(A)], A[3:2]);			   else			      output_byte(main_cache[main_cache_line(A)], A[3:0]);			end // if (in_main_cache(A))		  else		     if (in_victim_cache(A))			begin			   `ifdef TALK			      $display("CPUside: Victim cache hit (will swap cache w. main)");			   `endif			   if (MAS[1])			      output_word(victim_cache[victim_cache_line(A)], A[3:2]);			   else			      output_byte(victim_cache[victim_cache_line(A)], A[3:0]);			   swap_caches(A);			end // if (in_victim_cache)		     else			begin			   if (main_cache_valid[main_cache_line(A)])			      // Only moving it if the line is valid is a small optimisation 			      //  for the victim cache.			      // Probably not beneficial for a normal CPU, but will make a 			      //  difference in the small tests that will be run here!			      // Will also make debugging easier.			      // In other words, the above "if" should probably be removed,			      //  but I'm leaving it in for now.			      move_main_to_victim(A);			   // Stall until Memoryside is ready			   while (st_busy)			      begin				 cpu_busy = 1;				 @(posedge sysclk) enter_new_cpu_state(`CPUSIDE_WAIT2);			      end // while (st_busy)		  			   // Memoryside now ready, so give it its next piece of work.			   Load_Trigger = 1;			   cpu_busy = 1;  // Ensure that CPU waits...			   // Get data from Memoryside as it becomes ready			   while (ld_busy | (present_cpu_state != `CPUSIDE_LOADING))			      begin				 @(posedge sysclk) enter_new_cpu_state(`CPUSIDE_LOADING);				 cpu_busy = 1;				 #2;				 if (load_from_mem_req)				    input_word(main_cache[main_cache_line(A)], 					       load_from_mem_offset, 					       load_from_mem_data, 					       main_cache_dedsec[main_cache_line(A)]);			      end // while (ld_busy)			   @(posedge sysclk) enter_new_cpu_state(`CPUSIDE_LOADEND);			   // Calculate DEDSEC bits for the newly loaded cache line			   main_cache_dedsec[main_cache_line(A)] <= @(posedge sysclk) 			      dedsec_bits(main_cache[main_cache_line(A)]);			   			   // Save the tag			   main_cache_tag[main_cache_line(A)] <= @(posedge sysclk) 			      A[`MAIN_CACHE_TAG_BIT_HIGH:`MAIN_CACHE_TAG_BIT_LOW];			   			   // Mark that this line is valid			   main_cache_valid[main_cache_line(A)] <= @(posedge sysclk) 1;	$display ("%d: A=%h  D=%h", $time, A, main_cache[main_cache_line(A)]);		   			   // Output to ARM Core			   if (MAS[1])			      output_word(main_cache[main_cache_line(A)], A[3:2]);			   else			      output_byte(main_cache[main_cache_line(A)], A[3:0]);			   			   `ifdef TALK			      $display("CPUside: Load (from mem) result output (line=%h)", 				       main_cache_line(A));			   `endif			end // else: !if(in_victim_cache)	       end // else: !if(nRW)      end // always begin   task enter_new_cpu_state;      input [`CPUSIDE_NUM_STATE_BITS-1:0] this_state;      begin	 #0 Dout = 32'hzzzzzzzz;	 #1 present_cpu_state = this_state;	 Load_Trigger = 0;	 Store_Trigger = 0;	 cpu_busy = 0;	 // Any more to be added?      end   endtask // enter_new_cpu_state      endmodule

⌨️ 快捷键说明

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