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

📄 sequencer.v

📁 键盘和USB与PC机的接口程序
💻 V
📖 第 1 页 / 共 2 页
字号:
/*
**  SEQUENCER
**
**  This core adheres to GNU Public Licence
**  Jeung Joon Lee  ***  www.cmosexod.com
**  joon.lee@quantum.com
**
**	JJL 12/12/98	
**  updated 3/16/2000
**
**
**  This is the sequencer for the POPCORN 8bit microprocessor.
**  Controls all of the control signals.
**
**  This sequencer controls these following signals of the datapath "popcorn"
**
**
**
*/
module sequencer   (sys_clk,
					phase_1_clk,
					sys_rst,
					w_acc,
					w_ax,
					w_bx,
					w_p,
					w_flag,					
					bbus_mux,
					alu_func,
					pc_mux,
					addx_mux,
					sp_mux,
					flag_mux,
					w_sp,
					w_pc,
					w_oplo,
					w_ophi,
					w_opl,
					reg_opl,
					code_cs_l,
					code_rd_l,
					sram_cs_l,
					code_wr_l,
					reg_flag,
					data_bus_wr,
					next_state
 	             );

input        		sys_clk,sys_rst,phase_1_clk;
input  [7:0]    	reg_opl;
input  [2:0] 		reg_flag;
output       		w_acc,w_ax,w_bx,w_p,w_flag,pc_mux,w_pc;
output       		w_opl,w_oplo,w_ophi,code_cs_l,code_rd_l;
output [3:0] 		alu_func;
output [2:0] 		bbus_mux;
output [3:0] 		next_state;
output [1:0]		addx_mux;
output				sp_mux, w_sp, sram_cs_l, code_wr_l, data_bus_wr;
output				flag_mux;

reg    [5:0] 		next_state;
reg          		code_cs_l,code_rd_l_gate;
reg		     		w_opl_gate,w_acc_gate,w_ax_gate,w_bx_gate;
reg					w_p_gate,w_flag_gate,pc_mux;
reg		     		w_oplo_gate,w_ophi_gate,w_pc_gate;
reg    [3:0] 		alu_func;
reg    [2:0] 		bbus_mux;
reg          		dummy;
reg	   [1:0]        addx_mux;
reg					w_sp_gate, sp_mux, sram_cs_l, code_wr_l_gate,data_bus_wr;
reg					flag_mux;

parameter state_s0  =6'b000001;
parameter state_s1  =6'b000010;
parameter state_s2  =6'b000100;
parameter state_s3  =6'b001000;
parameter state_s4	=6'b010000;
parameter state_s5  =6'b100000;

assign w_acc = w_acc_gate;
assign w_ax  = w_ax_gate;
assign w_bx  = w_bx_gate;
assign w_p   = w_p_gate;
assign w_flag= w_flag_gate;
assign w_pc  = w_pc_gate;
assign w_sp  = w_sp_gate;
assign w_oplo= w_oplo_gate | phase_1_clk;		// asynchronous reg
assign w_ophi= w_ophi_gate | phase_1_clk;		// asynchronous reg
assign w_opl = w_opl_gate  | phase_1_clk; 		// asynchronous reg
assign code_rd_l = code_rd_l_gate | phase_1_clk;	// code rom rd
assign code_wr_l = code_wr_l_gate | phase_1_clk;

/*
** Behavioral description of the Sequencer State machine
**
** synchronous state machine, transitions on the rising edge of sys_clk
*/
always @(posedge sys_clk or negedge sys_rst) begin
	if (~sys_rst) begin   // rst
		code_cs_l 		<= 1'b1;
		code_rd_l_gate 	<= 1'b1;
		code_wr_l_gate  <= 1'b1;
		sram_cs_l		<= 1'b1;
		alu_func  		<= 4'b0000;
		w_acc_gate     	<= 1'b1;
		w_ax_gate      	<= 1'b1;
		w_bx_gate	   	<= 1'b1;
		w_p_gate       	<= 1'b1;
		w_flag_gate    	<= 1'b1;
		w_opl_gate     	<= 1'b1;
		w_oplo_gate    	<= 1'b1;
		w_ophi_gate    	<= 1'b1;
		bbus_mux       	<= 2'b00;				
		addx_mux		<= 2'b01;
		pc_mux         	<= 1'b1;
		sp_mux			<= 1'b1;
		flag_mux		<= 1'b1;
		w_pc_gate      	<= 1'b1;
		w_sp_gate		<= 1'b1;
		data_bus_wr		<= 1'b1;
//		port_bus_ena	<= 1'b0;
		next_state     	<= state_s0;
	end	
	else case(next_state)
		/*
		** FETCH OPCODE STATE. (at beginning of s1 opcode is latched into reg_opl)
		*/
		state_s0: begin     // *****2
				code_cs_l      <= 1'b0;	// enable code cs
                code_rd_l_gate <= 1'b0;	// enable code rd
				code_wr_l_gate <= 1'b1;
				sram_cs_l	   <= 1'b1;
				alu_func       <= 4'bx;
				w_acc_gate     <= 1'b1;
				w_ax_gate      <= 1'b1;
				w_bx_gate	   <= 1'b1;
				w_p_gate       <= 1'b1;
				w_flag_gate    <= 1'b1;
				w_opl_gate     <= 1'b0;	// latch opl at s1
				w_oplo_gate    <= 1'b1;
                w_ophi_gate    <= 1'b1;
				bbus_mux       <= 2'b00;				
				addx_mux	   <= 2'b01;
				pc_mux         <= 1'b1;
				sp_mux		   <= 1'b1;
				flag_mux	   <= 1'b1;
				w_pc_gate      <= 1'b1;
				w_sp_gate	   <= 1'b1;
				data_bus_wr	   <= 1'b1;
				//port_bus_ena	<= 1'b0;
				next_state     <= state_s1;
		end
		/*
		** REGISTER DIRECT INSTRUCTIONS 1 byte, 2 cycle instructions
		** these are: stacc, ldacc, and alu ops
		*/
		state_s1: begin	// ******** 2	

                begin
				    code_cs_l           <= 1'b1;  // disable cs and rd from code ram
				    code_rd_l_gate      <= 1'b1;
				    w_opl_gate          <= 1'b1;  // disable opcode latch gate		
                end

				// ALU opcode - register direct
				if((reg_opl[7:6]==2'b00)&&(reg_opl[2:0]!=3'b111)) begin
					alu_func       <= reg_opl[6:3];
					w_acc_gate     <= 1'b0;  // latch acc with result on s0
					w_flag_gate    <= 1'b0;	// latch reg result on s0			
					bbus_mux       <= reg_opl[2:0];									
					w_pc_gate      <= 1'b0;  // increment pc on s0
					next_state     <= state_s0;					
				end
				// CMPACC opcode - register direct
				else if((reg_opl[7:3]==5'b01000)&&(reg_opl[2:0]!=3'b111)) begin
					alu_func       <= 4'b0001;  // alu subtract
					w_flag_gate    <= 1'b0;	// latch reg result on s0
					bbus_mux       <= reg_opl[2:0];				
					w_pc_gate      <= 1'b0;  // increment pc on s0
					next_state     <= state_s0;					
				end				
				// LDACC - register direct
				else if ((reg_opl[7:3]==5'b10001)&&(reg_opl[2:0]!=3'b111)) begin
					alu_func       <= 4'b1000;  // alu=select b bus
					w_acc_gate     <= 1'b0;     // latch acc on s0
					bbus_mux       <= reg_opl[2:0];				
					w_pc_gate      <= 1'b0;  // increment pc on s0
					next_state     <= state_s0;								
				end
				// STACC - register direct
				else if ((reg_opl[7:3]==5'b10010)&&(reg_opl[2:0]!=3'b111)) begin
					alu_func       <= 4'b1001;  // alu=select a bus
					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'b100: begin
									w_flag_gate	<= 1'b0;
									flag_mux	<= 1'b0;
								end
						3'b101: w_p_gate       <= 1'b0;
						default: dummy         <= 1'b0;  // do nothing
					endcase					
					bbus_mux       <= 3'b001;  // anything but 3'b101 (port)
					w_pc_gate      <= 1'b0;  // increment pc in s0
					next_state	   <= state_s0;								
				end
				// PUSH , write out to [SP] and decrement SP
				// push does this:   [SP] <- reg,  SP=SP-1
				else if(reg_opl[7:3]==5'b01110) begin		
					if (reg_opl[2:0]==3'b000) begin
						alu_func   <= 4'b1001;  // select c_bus=acc
					end else begin
						alu_func   <= 4'b1000;  // select c_bus=b_bus
					end
					bbus_mux       <= reg_opl[2:0];	
					sp_mux		   <= 1'b1;		// sp = sp -1
					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'b0;  	// increment pc on s0
					next_state     <= state_s0;					
				end
				// POP, RET part I, increment SP
				// pop does this:  
				//		SP=SP+1
				//		reg_ophi <- [SP]
				//		SP=SP+1
				//		reg_oplo <- [SP]
				else if (reg_opl[7:3]==5'b01111 | reg_opl[7:0]==8'b11011110) begin					
					alu_func	   <= 4'b1000;	// c_bus = b_bus
					bbus_mux	   <= 3'b110;	// b_bus = d_bus
					sp_mux		   <= 1'b0;		// sp = sp + 1
					w_sp_gate	   <= 1'b0;		// allow sp to increment
					next_state     <= state_s2;					
				end

				// Immediate mode, so need to go and fetch one or two operands.
				// setup the PC so it increments to 1 and cs and rd gates
				// are asserted
				else begin
					alu_func       <= 4'b1000;
					w_acc_gate     <= 1'b1;
					w_ax_gate      <= 1'b1;
					w_bx_gate	   <= 1'b1;
					w_p_gate       <= 1'b1;
					w_oplo_gate    <= 1'b1;					
					bbus_mux       <= 3'b110;   // show d_bus on c_bus 				
					pc_mux         <= 1'b1;
					w_pc_gate      <= 1'b0;  	// increment pc on s2
					next_state     <= state_s2;									
				end
		end
		
		/*
		** IMMEDIATE INSTRUCTIONS.  2 bytes, 3 cycle insruction
		** these are:  ldi, alu ops.
		*/
		state_s2: begin
				// LDI - load immediate 8 bit value to register 

⌨️ 快捷键说明

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