// Implements: // JTAG communication with the Personal Computer // Control Panel Functions // // Name : P8_Control_020.v // Version: 020 // Date : 03-01-2012 // Author : Theo Engel // Contact: Info@theoengel.nl // version 011: initial version (04-03-2010) // version 012: change in COMMAND ACTION read/write handling (SWITCHES state control) (19-10-2010) // version 013: 012 still produces read switches errors => implement error check // version 014: read switches resend capability // version 015: read switches resend capability removed // version 016: fast ptr logic changed // version 017: reset fptr logic when fptr is (re)attached // version 018: remove fptr status as output parameter to the green leds // version 019: fptr logic changed // version 020: disk-offset register control added (03-01-2012) module P8_Control (// USB JTAG iRXD_DATA,oTXD_DATA,iRXD_Ready,iTXD_Done,oTXD_Start, // CPU Registers/Switches iR, iPC, iA15, oR_RDA, // read scratchpad oR, oR_WRA, oR_WRE, // write scratchpad iIR, // instruction register iPSW, // PSW // CPU Control oRun,oStep,oStop,oCP,oClkSw,oMC_n,iRunning,iError,iEnb, iPR, oPR, oPR_WR, // break point register iDO, oDO, oDO_WR, // disk-offset register // SRAM oSR_DATA,iSR_DATA,oSR_ADDR,oSR_WE_N,oSR_OE_N, // Peripheral interfaces // TTY TtyCharIn, iTtyInReq, oTtyIChar, iTty, iTtyCharO, oTtyOutReady, // PTR iPtrInReq,oPtrIChar,PtrCharIn,iPtrTry,f_FPTR, // PTP iPtp,iPtpO,oPtpOutReady, // Control iCLK,iRST_n,of_SWS); // USB JTAG input wire [7:0] iRXD_DATA; input wire iRXD_Ready,iTXD_Done; output wire [7:0] oTXD_DATA; output wire oTXD_Start; // SRAM input wire [15:0] iSR_DATA; output reg [15:0] oSR_DATA; output reg [14:0] oSR_ADDR; // word address output wire oSR_WE_N,oSR_OE_N; // CPU Registers input wire [15:0] iR, iPC, iA15; // read scratchpad: register input output reg [3:0] oR_RDA; // read scratchpad: register to read output reg [15:0] oR; // write scratchpad: register output output reg [3:0] oR_WRA; // write scratchpad: register to write output reg oR_WRE; // write scratchpad: write enable input wire [15:0] iIR; // instruction register: input input wire [15:0] iPSW; // PSW: input input wire [15:0] iPR; // breakpoint register: input output reg [15:0] oPR; // breakpoint register: output output reg oPR_WR; // breakpoint register: write enable input wire [15:0] iDO; // disk-offset register: input output reg [15:0] oDO; // disk-offset register: output output reg oDO_WR; // disk-offset register: write enable // CPU Control input wire iRunning,iError,iEnb; output reg oRun,oStep,oStop,oCP,oClkSw; output wire oMC_n; // IO Control Unit interfaces // TTY input wire iTtyInReq; // signals input mode to the TTY/PC input wire iTtyCharO; // output signal: if 1, char for output is available output reg oTtyIChar; // TTY/PC signals CU that an input char is available output reg oTtyOutReady; // signals that the character is sent to the TTY/PC output reg [7:0] TtyCharIn; // PC=>cu input wire [7:0] iTty; // cu=>PC; input from TTY Register // PTR input wire iPtrInReq; // signals input mode to the PTR/PC (cu=>PC) output wire oPtrIChar; // PTR/PC signals CU that an input char is available (PC=>cu) output wire [7:0] PtrCharIn; // read byte (PC=>cu) input wire iPtrTry; // PTR-CU signals byte is transferred to A-reg (used by FPTR only) output f_FPTR; // signals selected //// added for fast papertape reader support reg [3:0] mFptr_ST; // state register reg [39:0] mFptr; reg f_FPTR; // JTAG input selector reg mFptrIchar; // reader logic has character for PTR cu (to oPtrIChar) reg [7:0] FptrCharIn; // character for the PTR CU (to PtrCharIn) reg fptr_reset; // reset in case of attach/detach/reset ptr reg [9:0] fptr_delay; // PTP input wire [7:0] iPtp; // in from cu => output via JTAG to PC input wire iPtpO; // character output request (set by CU) output reg oPtpOutReady; // signal to the cpu/cu that the character is sent // RTC switch reg mClk_Son, mClk_Soff; // Clock switch on and off signal // Set MasterClear assign oMC_n = ~(iRST_n ^ m_MC_n); // Control input iCLK,iRST_n; output reg of_SWS; ///////////////////////////////////////////////////////////////////////////////////////// // Internal Registers reg [63:0] CMD; // JTAG shift register (input) // SRAM State Register reg [2:0] mSR_ST; // SRAM Control Register reg mSR_WRn,mSR_Start; // SREG State Register (scratchpad) reg [2:0] mR_ST; // SW State Register reg [3:0] mSWS_ST; // PRREG State Register reg [1:0] mPR_ST; // DOREG State Register reg [1:0] mDO_ST; // PSW State Register reg [1:0] mPSW_ST; // Flags set when target is selected reg f_SETUP; reg f_SRAM,f_SREG,f_PRREG,f_DOREG,f_PSW; // USB JTAG TXD Output reg mSR_TXD_Start; // output from SRAM reg [7:0] mSR_TXD_DATA; reg mR_TXD_Start; // output from Scratchpad Register reg [7:0] mR_TXD_DATA; reg mSWS_TXD_Start; // output from SWITCHES/STATE reg [7:0] mSWS_TXD_DATA; reg mPR_TXD_Start; // output from PR Register reg [7:0] mPR_TXD_DATA; reg mDO_TXD_Start; // output from DO Register reg [7:0] mDO_TXD_DATA; reg mPSW_TXD_Start; // output from PSW Register reg [7:0] mPSW_TXD_DATA; // TXD Output Selection flags reg sel_SR,sel_R,sel_SWS,sel_PR,sel_DO,sel_PSW; // JTAG input Register: input message layout wire [7:0] CMD_Action = CMD[63:56]; wire [7:0] CMD_Target = CMD[55:48]; wire [23:0] CMD_ADDR = CMD[47:24]; // 24 bit (3 bytes) wire [15:0] CMD_DATA = CMD[23: 8]; // 16 bit (2 bytes) wire [7:0] CMD_MODE = CMD[ 7: 0]; wire [7:0] Pre_Target = CMD[47:40]; // Pre_Target == Target previous clock cycle wire [7:0] CMD_RADDR = CMD[47:40]; // Scratchpad register address (shares part of CMD_ADDR) wire [7:0] CMD_TTYin = CMD[31:24]; // TTYin shares part of CMD_ADDR // CPU Control Registers/Wires (set or reset by the Console) reg m_MC_n; ////////////////// Command Action ///////////////////// parameter SETUP = 8'h61; // select JTAG output registers parameter WRITE = 8'h83; parameter READ = 8'h94; ////////////////// Command Target ///////////////////// parameter LED = 8'hF0; parameter SEG7 = 8'hE1; parameter SRAM = 8'hA1; parameter SET_REG = 8'h4C; // select JTAG output registers parameter SREG = 8'hA3; // scratchpad parameter PSW = 8'hA9; // PSW parameter PRREG = 8'hE5; // breakpoint parameter DOREG = 8'hF5; // disk-offset parameter SWITCHES = 8'hF1; parameter FPTR = 8'hD2; // fast ptr ////////////////// Command Mode ///////////////////// parameter OUTSEL = 8'h33; // select JTAG output registers parameter NORMAL = 8'hAA; ///////////////////////////////////////////////////////// ///////////// Set JTAG TXD Output Selection ///////////// always@(posedge iCLK or negedge iRST_n) begin if(!iRST_n) begin sel_SWS <=1'b0; sel_SR <=1'b0; sel_R <=1'b0; sel_PR <=1'b0; sel_DO <=1'b0; sel_PSW <=1'b0; f_SETUP <=1'b0; end else begin if(iRXD_Ready && (Pre_Target == SET_REG) ) f_SETUP<=1'b1; if(f_SETUP) begin if( (CMD_Action == SETUP) && (CMD_MODE == OUTSEL) && (CMD_ADDR == 24'h123456) ) begin case(CMD_DATA[7:0]) SRAM: begin sel_SWS <=1'b0; sel_SR <=1'b1; sel_R <=1'b0; sel_PR <=1'b0; sel_DO <=1'b0; sel_PSW <=1'b0; end SREG: begin sel_SWS <=1'b0; sel_SR <=1'b0; sel_R <=1'b1; sel_PR <=1'b0; sel_DO <=1'b0; sel_PSW <=1'b0; end SWITCHES: begin sel_SWS <=1'b1; sel_SR <=1'b0; sel_R <=1'b0; sel_PR <=1'b0; sel_DO <=1'b0; sel_PSW <=1'b0; end PRREG: begin sel_SWS <=1'b0; sel_SR <=1'b0; sel_R <=1'b0; sel_PR <=1'b1; sel_DO <=1'b0; sel_PSW <=1'b0; end DOREG: begin sel_SWS <=1'b0; sel_SR <=1'b0; sel_R <=1'b0; sel_PR <=1'b0; sel_DO <=1'b1; sel_PSW <=1'b0; end PSW: begin sel_SWS <=1'b0; sel_SR <=1'b0; sel_R <=1'b0; sel_PR <=1'b0; sel_DO <=1'b0; sel_PSW <=1'b1; end endcase end f_SETUP<=1'b0; end end end assign oTXD_Start = (sel_SWS) ? mSWS_TXD_Start: (sel_SR) ? mSR_TXD_Start: (sel_R) ? mR_TXD_Start: (sel_PSW) ? mPSW_TXD_Start: (sel_PR) ? mPR_TXD_Start: (sel_DO) ? mDO_TXD_Start: 1'b0; assign oTXD_DATA = (sel_SWS) ? mSWS_TXD_DATA: (sel_SR) ? mSR_TXD_DATA: (sel_R) ? mR_TXD_DATA: (sel_PSW) ? mPSW_TXD_DATA: (sel_PR) ? mPR_TXD_DATA: (sel_DO) ? mDO_TXD_DATA: 8'h00; ///////////////////////////////////////////////////////// ////// JTAG Input Shift Register ////// always@(posedge iCLK or negedge iRST_n) begin if(!iRST_n) CMD <= 0; else begin if(iRXD_Ready) CMD <= {CMD[55:0],iRXD_DATA}; end end ///////////////////////////////////////////////////////// ///////// FAST PAPERTAPE READER INPUT /////////////////// // Between the presentation of the bytes, there must be // time after an INR for the execution of an CIO-stop. // The CIO-stop comes not directly after an INR (in DOM // there are 10's of instructions between the last INR // of a record and the CIO-stop). The delay is meant to // arrange this. (with a 1000 cps reader, the time between // 2 bytes is 1 msec, is about 500 instructions on a P856; // with a delay of 10 bit = 1024 clock pulses we have about // 100 to 200 instructions). always@(posedge iCLK or negedge oMC_n or posedge fptr_reset) begin if((! oMC_n) || fptr_reset) begin mFptr <= 40'h0000000000; FptrCharIn <= 8'h00; f_FPTR <= 1'b0; mFptrIchar <= 1'b0; mFptr_ST <= 4'b0000; fptr_delay <= 10'b0000000000; end else begin if(iRXD_Ready && (Pre_Target == FPTR)) begin f_FPTR <= 1'b1; mFptr_ST <= 4'b0000; end if(f_FPTR) begin case(mFptr_ST) 4'b0000: begin if( (CMD_Action == WRITE) && (CMD_MODE == NORMAL) && (CMD_Target == FPTR)) begin mFptr <= CMD[47:8]; // buffer 5 incoming bytes mFptr_ST <= 4'b0001; FptrCharIn <= 8'h00; mFptrIchar <= 1'b0; fptr_delay <= 10'b0000000000; end else begin mFptr <= 40'h0000000000; f_FPTR <= 1'b0; mFptr_ST <= 4'b0000; FptrCharIn <= 8'h00; mFptrIchar <= 1'b0; fptr_delay <= 10'b0000000000; end end 4'b0001: // PTR CU is waiting for a byte (signaled by iPtrInReq) // the iPtrInReq signal was sent to the PC which results in the 5 buffered bytes. // So the 1st byte can now be send to the CU in reply of the iPtrInReq signal begin mFptrIchar <= 1'b1; FptrCharIn <= mFptr[7:0];// byte 1 for the CU mFptr_ST <= 4'b0010; end 4'b0010: begin mFptr_ST <= 4'b0010; if(iPtrTry) // byte 1 transferred to A-reg? begin mFptr_ST <= 4'b0011; // yes mFptrIchar <= 1'b0; FptrCharIn <= 8'h00; fptr_delay <= 10'b0000000001; end end 4'b0011: begin // wait if(| fptr_delay) begin fptr_delay <= fptr_delay + 1'b1; mFptr_ST <= 4'b0011; end else mFptr_ST <= 4'b0100; end 4'b0100: begin // 2nd byte mFptr_ST <= 4'b0100; if(iPtrInReq) begin mFptrIchar <= 1'b1; FptrCharIn <= mFptr[15:8];// byte 2 for the CU mFptr_ST <= 4'b0101; end end 4'b0101: begin mFptr_ST <= 4'b0101; if(iPtrTry) // byte 2 transferred to A-reg? begin mFptr_ST <= 4'b0110; // yes mFptrIchar <= 1'b0; FptrCharIn <= 8'h00; fptr_delay <= 10'b0000000001; end end 4'b0110: begin // wait if(| fptr_delay) begin fptr_delay <= fptr_delay + 1'b1; mFptr_ST <= 4'b0110; end else mFptr_ST <= 4'b0111; end 4'b0111: begin // 3rd byte mFptr_ST <= 4'b0111; if(iPtrInReq) begin mFptrIchar <= 1'b1; FptrCharIn <= mFptr[23:16];// byte 3 for the CU mFptr_ST <= 4'b1000; end end 4'b1000: begin mFptr_ST <= 4'b1000; if(iPtrTry) // byte 3 transferred to A-reg? begin mFptr_ST <= 4'b1001; // yes mFptrIchar <= 1'b0; FptrCharIn <= 8'h00; fptr_delay <= 10'b0000000001; end end 4'b1001: begin // wait if(| fptr_delay) begin fptr_delay <= fptr_delay + 1'b1; mFptr_ST <= 4'b1001; end else mFptr_ST <= 4'b1010; end 4'b1010: begin // 4th byte mFptr_ST <= 4'b1010; if(iPtrInReq) begin mFptrIchar <= 1'b1; FptrCharIn <= mFptr[31:24];// byte 4 for the CU mFptr_ST <= 4'b1011; end end 4'b1011: begin mFptr_ST <= 4'b1011; if(iPtrTry) // byte 4 transferred to A-reg? begin mFptr_ST <= 4'b1100; // yes mFptrIchar <= 1'b0; FptrCharIn <= 8'h00; fptr_delay <= 10'b0000000001; end end 4'b1100: begin // wait if(| fptr_delay) begin fptr_delay <= fptr_delay + 1'b1; mFptr_ST <= 4'b1100; end else mFptr_ST <= 4'b1101; end 4'b1101: begin // 5th byte mFptr_ST <= 4'b1101; if(iPtrInReq) begin mFptrIchar <= 1'b1; FptrCharIn <= mFptr[39:32];// byte 5 for the CU mFptr_ST <= 4'b1110; end end 4'b1110: begin mFptr_ST <= 4'b1110; if(iPtrTry) // byte 5 transferred to A-reg? begin mFptr_ST <= 4'b1111; // yes mFptrIchar <= 1'b0; FptrCharIn <= 8'h00; end end 4'b1111: begin // deselect f_FPTR <= 1'b0; mFptr_ST <= 4'b0000; end default: begin f_FPTR <= 1'b0; mFptr_ST <= 4'b0000; end endcase end end end // oPtrIchar signals the papertape reader CU that an input char is available (PC=>cu) assign oPtrIChar = mFptrIchar; // PtrCharIn has the byte for the papertape reader control unit assign PtrCharIn = FptrCharIn; ///////////// SWITCHES/STATE Control //////////////////// always@(posedge iCLK or negedge oMC_n) begin if(! oMC_n) begin m_MC_n <=1'b1; // active low, so high if inactive oRun <=1'b0; oStep <=1'b0; oStop <=1'b0; oCP <=1'b0; of_SWS <=1'b0; mSWS_TXD_Start <=1'b0; // Peripheral interfaces oTtyIChar <=1'b0; oTtyOutReady <= 1'b0; //TTY TtyCharIn[7:0] <= 8'b00000000; oPtpOutReady <=1'b0; //PTP mClk_Son <=1'b0; mClk_Soff <=1'b0; //RTC switch fptr_reset <=1'b0; //Fptr mSWS_ST <= 4'b0000; end else begin if(iRXD_Ready && (Pre_Target == SWITCHES)) begin of_SWS <= 1'b1; mSWS_ST <= 4'b0000; end if(of_SWS) begin case (mSWS_ST) 0: begin if( (CMD_Target == SWITCHES) && (CMD_Action == WRITE) && (CMD_MODE == NORMAL) ) mSWS_ST <= 4'b0001; else if( (CMD_Target == SWITCHES) && (CMD_Action == READ) && (CMD_MODE == NORMAL) ) mSWS_ST <= 4'b0100; else begin of_SWS <= 1'b0; // reset selection end end 1: //WRITE begin //// WRITE: Received from JTAG/PC (16 bits of which are 10 bits used) // 5432109876543210 // 15 : // 14 : // 13 : // 12 : // 11 : // 10 : // 9 : 0 // 8 : TTYin (1 => CMD_TTYin has a character for the teletype controler) // 7 : Stop (request stop execution of instructions: => CPU sets iRunning=0) // 6 : Step (request execution of a single instruction) // 5 : Run (request execution of instructions until HLT or Stop: => CPU sets iRunning=0) // 4 : Master Clear // 3 : Panel Interrupt // 2 : RTC on // 1 : RTC off // 0 : fptr reset //// //// !!!!! of the switches Master Clear, Run, Step, Stop ONLY ONE is allowed //// !!!!! to be activated in a single request //// !!!!! AND //// !!!!! Master Clear, Run, Step, are not allowed when iRunning=1 (ignored) //// !!!!! Stop, TTYin are only allowed when iRunning=1 (otherwise ignored) //// if(CMD_DATA[4] && (! iRunning)) begin // MasterClear m_MC_n <=1'b0; // keep for 1 clockpulse low oRun <=1'b0; oStep <=1'b0; oStop <=1'b0; oCP <=1'b0; oTtyIChar <=1'b0; end if(CMD_DATA[5] && (! iRunning)) begin // Run oRun <=1'b1; // keep for 1 clockpulse high m_MC_n <=1'b1; oStep <=1'b0; oStop <=1'b0; oCP <=1'b0; oTtyIChar <=1'b0; end if(CMD_DATA[6] && (! iRunning)) begin // Step oStep <= 1'b1; // keep for 1 clockpulse high oRun <= 1'b0; m_MC_n <= 1'b1; oStop <= 1'b0; oCP <= 1'b0; oTtyIChar <= 1'b0; end if(CMD_DATA[7] & iRunning) begin // Stop oStop <=1'b1; // keep for 1 clockpulse high m_MC_n <=1'b1; oStep <=1'b0; oRun <=1'b0; oCP <=1'b0; oTtyIChar <=1'b0; end if(CMD_DATA[3] & iRunning) begin // Panel Interrupt oStop <=1'b0; // keep for 1 clockpulse high m_MC_n <=1'b1; oStep <=1'b0; oRun <=1'b0; oCP <=1'b1; oTtyIChar <=1'b0; end if(CMD_DATA[8]) begin //TTYin: char available for tty cu in fpga m_MC_n <=1'b1; oRun <=1'b0; oStep <=1'b0; oStop <=1'b0; oCP <=1'b0; oTtyIChar <=1'b1; TtyCharIn[7:0] <= CMD_TTYin[7:0]; end if(CMD_DATA[2]) begin // request to switch the Real Time Clock On mClk_Son <= 1'b1; // keep for 1 clockpulse high end if(CMD_DATA[1]) begin // request to switch the Real Time Clock Off mClk_Soff <= 1'b1; // keep for 1 clockpulse high end if(CMD_DATA[0]) begin // reset fptr logic in case of attach/detach/reset ptr fptr_reset <= 1'b1; // keep for 1 clockpulse high end mSWS_ST <= 2; end 2: // WRITE (pc=>cu) cycle 2 //begin // if(CMD_DATA[8]) // begin // if(iTtyInReq) // mSWS_ST <= 2; // else // begin // mSWS_ST <= 3; // oTtyIChar <=1'b0; // TtyCharIn[7:0] <= 8'b00000000; // end // end // else //begin //oTtyIChar <= 1'b0; mSWS_ST <= 3; //end 3: // WRITE (pc=>cu) cycle 3 (last WRITE cycle; reset all signals) begin of_SWS <= 1'b0; // reset selection mSWS_TXD_Start <= 1'b0; m_MC_n <= 1'b1; oRun <= 1'b0; oStep <= 1'b0; oStop <= 1'b0; oCP <= 1'b0; oTtyOutReady <= 1'b0; oTtyIChar <= 1'b0; oPtpOutReady <= 1'b0; mClk_Son <= 1'b0; mClk_Soff <= 1'b0; fptr_reset <= 1'b0; mSWS_ST <= 4'b0000; TtyCharIn[7:0] <= 8'b00000000; end 4: //READ begin //// READ: send state to JTAG/PC (5*8 bits):STATE(8b) IR(16b) TYout(8b) PUout(8b) // 76543210 // 7: TTY Input Mode (1 in case TTY allows an input from the PC=>FPGA) // 6: TTYout request (1 in case the TTY requests the PC to get a char from FPGA and print) // 5: PTRin request (1 in case PTR requests an input character from the PC=>FPGA) // 4: PTPout request (1 in case the PTP requests the PC to get a char from FPGA and punch) // 3: ERROR bit // 2: ENB bit // 1: 1 (always 1 and used are check bit to see whether the JTAG transmission can be trusted) // (in case the received byte is 0, the received transmission is dropped) // 0: RUNNING (1 in case CPU is running) mSWS_TXD_Start <= 1'b1; mSWS_TXD_DATA <= {iTtyInReq, iTtyCharO, iPtrInReq & (~f_FPTR), // blocked when reader is active iPtpO, iError, iEnb, 1'b1, // check bit iRunning}; mSWS_ST <= 5; end 5:// READ (cu=>pc) cycle 2 (send IR, 1st byte) begin if(iTXD_Done) begin mSWS_TXD_DATA <= iIR[7:0]; mSWS_TXD_Start <= 1'b1; mSWS_ST <= 6; end end 6:// READ (cu=>pc) cycle 3 (send IR, 2nd byte) begin if(iTXD_Done) begin mSWS_TXD_DATA <= iIR[15:8]; mSWS_TXD_Start <= 1'b1; mSWS_ST <= 7; end end 7:// READ (cu=>pc) cycle 4 (send TTY output byte if available) begin if(iTXD_Done) begin mSWS_TXD_Start <= 1'b1; if(iTtyCharO) begin mSWS_TXD_DATA <= iTty; // input from TTY Register oTtyOutReady <= 1'b1; end else begin mSWS_TXD_DATA <= 8'b00000000; end mSWS_ST <= 8; end end 8:// READ (cu=>pc) cycle 5 (send PTP output byte if available) begin if(iTXD_Done) begin oTtyOutReady <= 1'b0; mSWS_TXD_Start <= 1'b1; if(iPtpO) // if 1, a char is available for output to the puncher (PC) begin mSWS_TXD_DATA <= iPtp; // input from PTP Register oPtpOutReady <= 1'b1; // character sent end else begin mSWS_TXD_DATA <= 8'b00000000; end mSWS_ST <= 9; end end 9:// READ (cu=>pc) cycle 6 (last read cycle; reset all signals begin if(iTXD_Done) begin of_SWS <= 1'b0; // reset selection mSWS_TXD_Start <= 1'b0; m_MC_n <= 1'b1; oRun <= 1'b0; oStep <= 1'b0; oStop <= 1'b0; oCP <= 1'b0; oTtyIChar <= 1'b0; oTtyOutReady <= 1'b0; TtyCharIn[7:0] <= 8'b00000000; oPtpOutReady <= 1'b0; mClk_Son <= 1'b0; mClk_Soff <= 1'b0; mSWS_ST <= 4'b0000; fptr_reset <=1'b0; end end default: begin of_SWS <= 1'b0; // reset selection mSWS_TXD_Start <= 1'b0; m_MC_n <= 1'b1; oRun <= 1'b0; oStep <= 1'b0; oStop <= 1'b0; oCP <= 1'b0; oTtyIChar <= 1'b0; oTtyOutReady <= 1'b0; TtyCharIn[7:0] <= 8'b00000000; oPtpOutReady <= 1'b0; mClk_Son <= 1'b0; mClk_Soff <= 1'b0; mSWS_ST <= 4'b0000; fptr_reset <=1'b0; end endcase end end end ///////////////////////////////////////////////////////// ////////////// SREG (Scratchpad) Control //////////////// always@(posedge iCLK or negedge oMC_n) begin if(!oMC_n) begin mR_TXD_Start <= 1'b0; f_SREG <= 1'b0; oR <= 16'h0000; oR_WRA <= 4'b0000; oR_WRE <= 1'b0; oR_RDA <= 4'b0000; end else begin if(iRXD_Ready && (Pre_Target == SREG)) begin f_SREG <= 1'b1; mR_ST <=0; oR_RDA <=0; oR_WRA <=0; oR_WRE <= 1'b0; end if(f_SREG) begin case(mR_ST) 0: begin if( (CMD_Action == WRITE) && (CMD_MODE == NORMAL) ) begin oR_WRA <=CMD_RADDR[3:0]; // addressed register oR <=CMD_DATA; // set value in selected register oR_WRE <= 1'b1; // write enable mR_ST <= 1; end else begin if( (CMD_Action == READ) && (CMD_MODE == NORMAL) ) begin oR_RDA <= CMD_RADDR[3:0]; // addressed register to read mR_ST <= 2; end else begin f_SREG <= 1'b0; end end end 1: begin // end write oR_WRE <= 1'b0; f_SREG <= 1'b0; // reset selection end 2: begin // read mR_TXD_DATA <= iR[7:0]; mR_TXD_Start <= 1'b1; mR_ST <= 3; end 3: begin if(iTXD_Done) begin mR_TXD_Start<= 1'b0; mR_ST <= 4; end end 4: begin mR_TXD_DATA <= iR[15:8]; mR_TXD_Start <= 1'b1; mR_ST <= 5; end 5: begin if(iTXD_Done) begin mR_TXD_Start<= 1'b0; f_SREG <= 1'b0; end end endcase end end end ///////////////////////////////////////////////////////// //////////// PRREG (Breakpoint) Control ///////////////// always@(posedge iCLK or negedge oMC_n) begin if(!oMC_n) begin mPR_TXD_Start <= 1'b0; f_PRREG <= 1'b0; oPR <= 16'h0000; oPR_WR <= 1'b0; end else begin oPR_WR <= 1'b0; if(iRXD_Ready && (Pre_Target == PRREG)) begin f_PRREG <=1'b1; mPR_ST <=0; end if(f_PRREG) begin if( (CMD_Action == WRITE) && (CMD_MODE == NORMAL) ) begin oPR <=CMD_DATA; // set value in PR-register oPR_WR <= 1'b1; f_PRREG <=1'b0; // reset selection end else begin case(mPR_ST) 0: begin if( (CMD_Action == READ) && (CMD_MODE == NORMAL) ) begin mPR_TXD_DATA <= iPR[7:0]; mPR_TXD_Start <= 1'b1; mPR_ST <= 1; end else begin f_PRREG <= 1'b0; end end 1: begin if(iTXD_Done) begin mPR_TXD_Start<=1'b0; mPR_ST <= 2; end end 2: begin mPR_TXD_DATA <= iPR[15:8]; mPR_TXD_Start <= 1'b1; mPR_ST <= 3; end 3: begin if(iTXD_Done) begin mPR_TXD_Start<= 1'b0; f_PRREG <= 1'b0; end end endcase end end end end ///////////////////////////////////////////////////////// //////////// DOREG (Disk-offset) Control /////////////// always@(posedge iCLK or negedge oMC_n) begin if(!oMC_n) begin mDO_TXD_Start <= 1'b0; f_DOREG <= 1'b0; oDO <= 16'h0000; oDO_WR <= 1'b0; end else begin oDO_WR <= 1'b0; if(iRXD_Ready && (Pre_Target == DOREG)) begin f_DOREG <=1'b1; mDO_ST <=0; end if(f_DOREG) begin if( (CMD_Action == WRITE) && (CMD_MODE == NORMAL) ) begin oDO <=CMD_DATA; // set value in DO-register oDO_WR <= 1'b1; f_DOREG <=1'b0; // reset selection end else begin case(mDO_ST) 0: begin if( (CMD_Action == READ) && (CMD_MODE == NORMAL) ) begin mDO_TXD_DATA <= iDO[7:0]; mDO_TXD_Start <= 1'b1; mDO_ST <= 1; end else begin f_DOREG <= 1'b0; end end 1: begin if(iTXD_Done) begin mDO_TXD_Start<=1'b0; mDO_ST <= 2; end end 2: begin mDO_TXD_DATA <= iDO[15:8]; mDO_TXD_Start <= 1'b1; mDO_ST <= 3; end 3: begin if(iTXD_Done) begin mDO_TXD_Start <= 1'b0; f_DOREG <= 1'b0; end end endcase end end end end ///////////////////////////////////////////////////////// //////////////// PSW Control ///////////////////// always@(posedge iCLK or negedge oMC_n) begin if(!oMC_n) begin mPSW_TXD_Start <= 1'b0; f_PSW <= 1'b0; end else begin if(iRXD_Ready && (Pre_Target == PSW)) begin f_PSW <= 1'b1; mPSW_ST <=0; end if(f_PSW) begin case(mPSW_ST) 0: begin if( (CMD_Action == READ) && (CMD_MODE == NORMAL) ) begin mPSW_TXD_DATA <= iPSW[7:0]; mPSW_TXD_Start <= 1'b1; mPSW_ST <= 1; end else begin f_PSW <= 1'b0; end end 1: begin if(iTXD_Done) begin mPSW_TXD_Start<= 1'b0; mPSW_ST <= 2; end end 2: begin mPSW_TXD_DATA <= iPSW[15:8]; mPSW_TXD_Start <= 1'b1; mPSW_ST <= 3; end 3: begin if(iTXD_Done) begin mPSW_TXD_Start <= 1'b0; f_PSW <= 1'b0; end end endcase end end end ///////////////////////////////////////////////////////// //////////////// RTC Control (Panel) ////////////// // 20 msec clock being switched On or Off via the Panel always@(posedge iCLK or negedge oMC_n) begin if(!oMC_n) begin oClkSw <= 1'b0; end else begin case(oClkSw) 1'b0: begin oClkSw <= 1'b0; if(mClk_Son) oClkSw <= 1'b1; end 1'b1: begin oClkSw <= 1'b1; if(mClk_Soff) oClkSw <= 1'b0; end endcase end end ///////////////////////////////////////////////////////// //////////////// SRAM Control ///////////////////// always@(posedge iCLK or negedge oMC_n) begin if(!oMC_n) begin mSR_TXD_Start <= 1'b0; mSR_WRn <= 1'b0; mSR_Start <= 1'b0; mSR_ST <=0; f_SRAM <= 1'b0; end else begin if(iRXD_Ready && (Pre_Target == SRAM)) begin f_SRAM <= 1'b1; mSR_ST <=0; end if(f_SRAM) begin case(mSR_ST) 0: begin if((CMD_MODE == NORMAL) && (CMD_Target == SRAM)) begin oSR_ADDR[14:0] <= CMD_ADDR[14:0]; //32kwords mSR_Start <= 1'b1; if(CMD_Action == WRITE) begin oSR_DATA <= CMD_DATA; mSR_WRn <= 1'b1; //write mSR_ST <= 1; end else if(CMD_Action == READ) begin mSR_WRn <= 1'b0; //read mSR_ST <= 2; end else begin f_SRAM <= 1'b0; mSR_Start <= 1'b0; mSR_WRn <= 1'b0; end end end 1: begin begin f_SRAM <= 1'b0; mSR_WRn <= 1'b0; mSR_Start <= 1'b0; mSR_ST <=0; end end 2: begin mSR_TXD_DATA <= iSR_DATA[7:0]; mSR_TXD_Start <= 1'b1; mSR_ST <= 3; end 3: begin if(iTXD_Done) begin mSR_TXD_Start <= 1'b0; mSR_ST <= 4; end end 4: begin mSR_TXD_DATA <= iSR_DATA[15:8]; mSR_TXD_Start <= 1'b1; mSR_ST <= 5; end 5: begin if(iTXD_Done) begin mSR_Start <= 1'b0; mSR_TXD_Start <= 1'b0; f_SRAM <= 1'b0; mSR_ST <=0; end end endcase end end end assign oSR_OE_N = ~(~mSR_WRn & mSR_Start ); assign oSR_WE_N = ~( mSR_WRn & mSR_Start ); endmodule