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

📄 sequencer.v

📁 键盘和USB与PC机的接口程序
💻 V
📖 第 1 页 / 共 2 页
字号:
				if ((reg_opl[7:6]==2'b10)&&(reg_opl[2:0]==3'b111)) begin
						alu_func  <= 4'b1000;
						case (reg_opl[5:3])  // latch the dest reg on s0
							3'b000: w_acc_gate  <= 1'b0;
							3'b001: w_ax_gate   <= 1'b0;
							3'b010: w_bx_gate	<= 1'b0;
							3'b101: w_p_gate    <= 1'b0;
							default: dummy      <= 1'b0;  //do nothing
						endcase						
						bbus_mux    <= 3'b110;				
						w_pc_gate   <= 1'b0;  // increment pc on s0
				        code_cs_l      <= 1'b0;    // allow -cs and -rd to code ram
				        code_rd_l_gate <= 1'b0;	  	
         				w_oplo_gate    <= 1'b0;    // assert oplo gate
						next_state  <= state_s0;						
				end
				// ALU op - immediate
				else if ((reg_opl[7:6]==2'b00)&&(reg_opl[2:0]==3'b111)) begin
						alu_func    <= reg_opl[6:3]; // get alu oprerationg from instruction
						w_acc_gate  <= 1'b0;  // latch acc on s0
						w_flag_gate <= 1'b0;  // update flag on s0												
						bbus_mux    <= 3'b110;				
						w_pc_gate   <= 1'b0;  // increment pc on s0
				        code_cs_l      <= 1'b0;    // allow -cs and -rd to code ram
				        code_rd_l_gate <= 1'b0;	  	
         				w_oplo_gate    <= 1'b0;    // assert oplo gate
						next_state  <= state_s0;						
				end
				// CMPACC op - immediate
				else if ((reg_opl[7:3]==5'b01000)&&(reg_opl[2:0]==3'b111)) begin
						alu_func    <= 4'b001; // alu to subtract
						w_flag_gate <= 1'b0;  // update flag on s0												
						bbus_mux    <= 3'b110; // bbus select d_bus				
						w_pc_gate   <= 1'b0;  // increment pc on s0
				        code_cs_l      <= 1'b0;    // allow -cs and -rd to code ram
         				code_rd_l_gate <= 1'b0;	  	
         				w_oplo_gate    <= 1'b0;    // assert oplo gate
						next_state  <= state_s0;						
				end 
				// POP, part II, load data from [SP]
				else if (reg_opl[7:3]==5'b01111) begin		
					code_cs_l	   <= 1'b1;		// don't read from code ram			
					alu_func	   <= 4'b1000;	// c_bus = b_bus
					bbus_mux	   <= 3'b110;	// b_bus = d_bus
					w_sp_gate	   <= 1'b1;		// disallow sp to change
					addx_mux	   <= 2'b10;	// select sp as addx source			
					sram_cs_l	   <= 1'b0;		// select sram
					code_rd_l_gate <= 1'b0;		// and read
					w_oplo_gate    <= 1'b0;		// and latch it into reg_oplo
					case (reg_opl[2:0])
						3'b000: w_acc_gate	<= 1'b0;
						3'b001: w_ax_gate	<= 1'b0;
						3'b010: w_bx_gate   <= 1'b0;
						3'b100: begin
									w_flag_gate	<= 1'b0;
									flag_mux	<= 1'b0;
								end
						default: w_p_gate	<= 1'b0;
					endcase
					w_pc_gate      <= 1'b0;  	// increment pc on s0
					next_state     <= state_s0;					
				end		
				// RET, part II, load hi byte of saved PC
				else if (reg_opl[7:0]==8'b11011110) begin
					code_cs_l	   <= 1'b1;		// don't read from code ram			
					alu_func	   <= 4'b1000;	// c_bus = b_bus
					bbus_mux	   <= 3'b110;	// b_bus = d_bus
					sp_mux		   <= 1'b0;		// increment SP
					w_sp_gate	   <= 1'b0;		// allow sp to change
					addx_mux	   <= 2'b10;	// select sp as addx source			
					sram_cs_l	   <= 1'b0;		// select sram
					code_rd_l_gate <= 1'b0;		// and read
					w_ophi_gate    <= 1'b0;		// and latch it into reg_ophi
     				code_rd_l_gate <= 1'b0;	  	
     				w_oplo_gate    <= 1'b0;    // assert oplo gate
					next_state	   <= state_s3;
				end
				// these are the 3 byte branching instructions. so go and fetch the high
				// byte operand
				else begin
					code_cs_l      <= 1'b0;    // allow -cs and -rd to code ram
					code_rd_l_gate <= 1'b0;	  	
					alu_func       <= 4'b1000;
					w_acc_gate     <= 1'b1;
					w_ax_gate      <= 1'b1;
					w_bx_gate	   <= 1'b1;
					w_p_gate       <= 1'b1;														
					bbus_mux       <= 3'b110;				
					pc_mux         <= 1'b1;
					w_pc_gate      <= 1'b0;  // increment pc on s3
    				w_oplo_gate    <= 1'b0;    // assert oplo gate
					next_state <= state_s3;
				end
		end				
		
		/*
		** BRANCHING INSTRUCTIONS,  3 bytes, 4 cycles
		*/
		state_s3: begin
//				w_ophi_gate   <= 1'b0;  // latch-in high byte operand
//				w_oplo_gate   <= 1'b1;  // deassert oplo gate
				// Branching operations - immediate
				if((reg_opl[7]==1'b1)&&(reg_opl[2:0]==3'b000)) begin
						alu_func    <= 4'b1000;  // for debug, c_bus=b_bus
						bbus_mux    <= 3'b110;	// for debug c_bus=d_bus			
						case(reg_opl[6:3])
							4'b0011: if(reg_flag[0]==1'b1) // JE
										pc_mux<=0; 		   	
									 else pc_mux<=1;
							4'b0100: if(reg_flag[0]==1'b0) // JNE
										pc_mux<=0; 
									 else pc_mux<=1;
							4'b0101: if(reg_flag[1]==1'b1) // JP
										pc_mux<=0; 
									 else pc_mux<=1;
							4'b0110: if(reg_flag[1]==1'b0) // JN
										pc_mux<=0; 
									 else pc_mux<=1;
							4'b0111: if(reg_flag[2]==1'b1) // JC
										pc_mux<=0; 
									 else pc_mux<=1;
							4'b1000: if(reg_flag[2]==1'b0) // JNC
										pc_mux<=0; 
									 else pc_mux<=1;
							4'b1001: pc_mux<=0;			   // JMP unconditional 
							default: pc_mux<=pc_mux;
						endcase
						w_pc_gate   <= 1'b0;	// increment pc on s0
						w_ophi_gate   <= 1'b0;  // latch-in high byte operand
						w_oplo_gate   <= 1'b1;  // deassert oplo gate
						next_state  <= state_s0;														
				end 
				// RET, part III, load lo byte of saved PC
				else if (reg_opl[7:0]==8'b11011110) begin
					code_cs_l	   <= 1'b1;		// don't read from code ram			
					alu_func	   <= 4'b1000;	// c_bus = b_bus
					bbus_mux	   <= 3'b100;	// b_bus = reg_pc hi
					sp_mux		   <= 1'b1;		// increment SP
					w_sp_gate	   <= 1'b1;		// disallow sp to change
					addx_mux	   <= 2'b10;	// select sp as addx source			
					sram_cs_l	   <= 1'b0;		// select sram
					code_rd_l_gate <= 1'b0;		// and read
					w_ophi_gate    <= 1'b1;		
					w_oplo_gate	   <= 1'b0;		// and latch it into reg_oplo
					pc_mux	       <= 1'b0;			
					w_pc_gate	   <= 1'b0;		// PC = d_bus	
					w_flag_gate    <= 1'b0;		// restore flag									
					next_state	   <= state_s0;
				end
				// CALL, part I. Allow the PC to be incremented so, that
				// the PC that is pushed onto the stack is pointing to 
				// the instruction after the call
				// what CALL does:
				//		[SP]    <- PC low byte
				//      SP=SP-1
				//		[SP]	<- PC high 4 bits
				//  	SP=SP-1 
				else if (reg_opl[7:0]==8'b11010110) begin
					w_pc_gate	<= 1'b0;
					w_ophi_gate   <= 1'b0;  // latch-in high byte operand
					w_oplo_gate   <= 1'b1;  // deassert oplo gate
					next_state  <= state_s4;
				end
				// Must be direct addresing instruction 
				else begin
					next_state	<= state_s4;
					w_ophi_gate   <= 1'b0;  // latch-in high byte operand
					w_oplo_gate   <= 1'b1;  // deassert oplo gate
					w_pc_gate  	<= 1'b1;      // deassert PC gate.
				end			
		end

		/*
		** DIRECT INSTRUCTIONS,  3 byte, 5 cycles
		*/
		state_s4: begin

				begin
					code_cs_l      <= 1'b1;    
					w_ophi_gate    <= 1'b1;  // latch-in high byte operand
				end

				// LMD and STM instructions
				if ((reg_opl[7:4]==5'b0110)&&(reg_opl[2:0]!=3'b111)) begin
						sram_cs_l 		<= 1'b0;	// select the sram
						addx_mux		<= 2'b00;	// select the sram address	
						w_pc_gate		<= 1'b0;	// increment pc on s0
						pc_mux			<= 1'b1;									
					    alu_func  <= 4'b1000;  // else c_bus = b_bus
						bbus_mux		<= 3'b110; // select d_bus by default
						// if it is STM
						if (reg_opl[3]==1'b1) begin	
							// while in STM, select c_bus=a_bus only if it's STM acc,xx
						    if (reg_opl[2:0]==3'b000)  begin
							   alu_func  <= 4'b1001;  // if DDD=acc c_bus=acc
 							end
							bbus_mux		<= reg_opl[2:0]; // select the approp reg
							code_wr_l_gate	<= 1'b0;
							data_bus_wr		<= 1'b0;	// drive data bus with c_bus							
						end
						// if it is LDM
						else begin
							code_rd_l_gate	<= 1'b0; 
							w_oplo_gate		<= 1'b0;   // latchin oplo with sram data on s4
            				code_rd_l_gate <= 1'b1;	  	
							case (reg_opl[2:0])    // latch approp dest reg on s0					
								3'b001: w_ax_gate      <= 1'b0;
								3'b010: w_bx_gate	   <= 1'b0;
								3'b101: w_p_gate       <= 1'b0;
								3'b100: begin
										w_flag_gate	<= 1'b0;
										flag_mux	<= 1'b0;
										end
								default: w_acc_gate    <= 1'b0;  // else, must be acc
							endcase
						end
						next_state <= state_s0;
				end // LMD if
				// CALL, 3 bytes, 6 cycles
				else if (reg_opl[7:0]==8'b11010110) begin
         				code_rd_l_gate <= 1'b1;	  	
						alu_func   	   <= 4'b1000;  // select c_bus=b_bus
						bbus_mux       <= 3'b011;	// select reg_pc low	
						sp_mux		   <= 1'b1;		// sp = sp - 1 on s5
						w_sp_gate	   <= 1'b0;		// allow sp to decrement
						addx_mux	   <= 2'b10;	// select sp as addx source			
						sram_cs_l      <= 1'b0;		// select sram
						code_wr_l_gate <= 1'b0;		// and write
						data_bus_wr	   <= 1'b0;	    // drive data bus with c_bus							
						w_pc_gate      <= 1'b1;  	// 
						next_state     <= state_s5;											
				end // call				
		end	// state_s4

		/*
		** CALL,  3 byte, 6 cycles
		** save to [SP], [SP-1] PC+1 not PC
		*/
		state_s5: begin
				if (reg_opl[7:0]==8'b11010110) begin
						alu_func   	   <= 4'b1000;  // select c_bus=b_bus
						bbus_mux       <= 3'b100;	// select reg_pc hi
						sp_mux		   <= 1'b1;		// sp = sp - 1 on s0
						w_sp_gate	   <= 1'b0;		// allow sp to decrement
						addx_mux	   <= 2'b10;	// select sp as addx source			
						sram_cs_l      <= 1'b0;		// select sram
						code_wr_l_gate <= 1'b0;		// and write
						data_bus_wr	   <= 1'b0;	    // drive data bus with c_bus							
						pc_mux		   <= 1'b0;		// PC = d_bus						
						w_pc_gate      <= 1'b0;  	// allow pc to be changed
						next_state     <= state_s0;
				end
		end // state_s5

	endcase  //state machine

end


endmodule

⌨️ 快捷键说明

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