<p>`define PROG1SEL 3 `define PROG2SEL 2 `define PROG3SEL 1 `define PROG4SEL 0</p><p>///////////////////////////////////////////////////////////////////////// //======// PIC 16F84 // PIC - Designed by PP Troendle under Iain Mc Nally // // // ////////////////////////////////////////////////////////////////////////// `include "opcodes.v" `timescale 100ps / 10 ps module pic(PC, inext, Clock, init, porta, portb, M, To_File, IR);</p><p>// I/O declarations output [12:0] PC; // address for external programm memory output [7:0] To_File; // for LCD debug mode output [7:0] M; // for LCD debug mode input [13:0] inext; // next instruction inout [7:0] porta, portb; // inout ports input Clock, init; // system clock and reset output [13:0] IR; // Instruction register</p><p>//wires wire [12:0] PC; // the programm counter (from reg pcl, pclath) wire [13:0] inext; //next instruction wire [7:0] porta, portb; //inout ports wire Clock, init; //system clock and reset wire [7:0] M, ALU_output; //ALU wire [6:0] ALU_funct; //ALU wire [7:0] Address_File; //FILE system wire [7:0] To_File; //FILE system wire [7:0] From_File; // FILE system wire [7:0] Data_ram; //FILE system wire WnR; //FILE system wire Z; // ALU status bit wire loadf, loadw; // control bits wire loadliteral; // control bits wire ram_en, opt_en, tmr_en, pcl_en, pch_en, sta_en, fsr_en; wire tra_en, trb_en, poa_en, pob_en, ee1_en, ee2_en, eed_en, eea_en, int_en; wire tra, trb;</p><p>//registers reg [13:0] IR; // Instruction register reg [12:0] PC1, PC2, PC3, PC4, PC5, PC6, PC7, PC8; // PC stack reg [7:0] pcl, pclath; // PC - the programm counter register reg [7:0] W; // the Accumulator reg [7:0] tmr0, status, fsr, eedata, eeadr; // Registers reg [7:0] intcon, option, eecon1, eecon2; // Registers ram ram1(Clock, WnR , Address_File, To_File, Data_ram); port port1(Clock, init, porta, From_File, To_File, loadf, tra_en, poa_en); port port2(Clock, init, portb, From_File, To_File, loadf, trb_en, pob_en); alu alu1(ALU_output, W, M, ALU_funct);</p><p>//ALU assign Z = (ALU_output == 8'b00000000)? 1'b1:1'b0; assign To_File = (IR[13:0]==`TRISA)||(IR[13:0]==`TRISB)? W : ALU_output; ///ALU SHOULD DO THAT assign ALU_funct = IR[13:7]; assign M = ( loadliteral )? IR[7:0]: From_File;</p><p>//PC assign PC = {pclath[4:0], pcl[7:0]}; //Control signals assign WnR = ((ram_en)&&(loadf)); assign loadf = ( ((IR[7]==1)&&(IR[13:12]==2'b00))|| //destination bit is one , file (IR[13:11]==3'b010)||tra||trb|| //`BCF,`BSF,`TRISA,`TRISB ((IR[13:8]==`CLRF)&&!(IR[7]==0)) ); //loadf not required in case W dest (CLRW) assign loadw = ( ((IR[7]==0)&&(IR[11:8]!=4'b0000)&& (IR[13:12]==2'b00))|| //destination bit is zero , W (IR[13:12]==2'b11)|| //immediate (IR[13:0]==`CLRW) ); //loadw required in case CLR assign loadliteral = (IR[13:12]==2'b11); //immediate</p><p>//indirect addressing assign Address_File[7:0] =(({status[5], IR[6:0]} == 'h00)|| ({status[5], IR[6:0]} == 'h80))? fsr:({status[5], IR[6:0]}); //RP0 value in status => 8 th bit // FILE ENABLE assign ram_en= (((Address_File >= 'h8C)&&(Address_File <= 'h CF))|| ((Address_File >= 'h0C)&&(Address_File <= 'h 4F))); assign opt_en= (Address_File == 'h81); assign tmr_en= (Address_File == 'h01); assign pcl_en= ((Address_File == 'h02)||(Address_File == 'h82)); assign pch_en= ((Address_File == 'h0A)||(Address_File == 'h8A)); assign sta_en= ((Address_File == 'h03)||(Address_File == 'h83)); assign fsr_en= ((Address_File == 'h04)||(Address_File == 'h84)); assign tra = (IR[13:0]==`TRISA); assign trb = (IR[13:0]==`TRISB); assign tra_en= ((Address_File == 'h85)||tra); assign trb_en= ((Address_File == 'h86)||trb); assign poa_en= (Address_File == 'h05); assign pob_en= (Address_File == 'h06); assign ee1_en= (Address_File == 'h88); assign ee2_en= (Address_File == 'h89); assign eed_en= (Address_File == 'h08); assign eea_en= (Address_File == 'h09); assign int_en= ((Address_File == 'h0B)||(Address_File == 'h8B));</p><p>// FILE assign From_File= (ram_en)? Data_ram : 8'bz; assign From_File= (opt_en)? option : 8'bz; assign From_File= (tmr_en)? tmr0 : 8'bz; assign From_File= (pcl_en)? pcl : 8'bz; assign From_File= (pch_en)? pclath : 8'bz; assign From_File= (sta_en)? status : 8'bz; assign From_File= (fsr_en)? fsr : 8'bz; assign From_File= (eed_en)? eedata : 8'bz; assign From_File= (eea_en)? eeadr : 8'bz; assign From_File= (ee1_en)? eecon1 : 8'bz; assign From_File= (ee2_en)? eecon2 : 8'bz; assign From_File= (int_en)? intcon : 8'bz;</p><p>//REGISTERS always @(posedge Clock) if (init) begin tmr0<=0; status<=8'b00011000; fsr<=0; eedata<=0; eeadr<=0; intcon<=0; option<=8'b11111111; //spec. eecon1<=0; eecon2<=0; end else begin if (loadf) begin //ram enable is done with the RnW //PC registers are done below if (opt_en) option <= To_File; if (tmr_en) tmr0 <= To_File; if (sta_en) status <= To_File; if (fsr_en) fsr <= To_File; if (eed_en) eedata <= To_File; if (eea_en) eeadr <= To_File; if (ee1_en) eecon1 <= To_File; if (ee2_en) eecon2 <= To_File; if (int_en) intcon <= To_File; end</p><p>// special cases TRIS and OPTION instructions if (IR[13:0]==`OPTION) option <= W;</p><p>//Z status[2]<=(ALU_output==0);</p><p>//DC case (IR[13:8]) `ADDWF: if ((M[3:0] + W[3:0])>= 'h 10) status[1] <= 1; `ADDLW: if ((M[3:0] + W[3:0])>= 'h 10) status[1] <= 1; `SUBWF: if (M[3:0] < W[3:0]) status[1] <= 1; `SUBLW: if (M[3:0] < IR[3:0]) status[1] <= 1; default: status[1] <= 0; endcase</p><p>//C case (IR[13:8]) `ADDWF: if ((M + W) >= 'h 100) status[0] <= 1; `ADDLW: if ((M + IR[7:0]) >= 'h 100) status[0] <= 1; `SUBWF: if (M < W) status[0] <= 1; `SUBLW: if (M < IR[7:0])status[0] <= 1; `RLF: if (M[7])status[0] <= 1; `RRF: if (M[0])status[0] <= 1; default: status[0] <= 0; endcase</p><p>//intcon if (IR[13:0] == `RETFIE) intcon[7] <=1; //GIE bit set end</p><p>//W always @(posedge Clock) if (init) W<=0; else if ( loadw ) W <= ALU_output;</p><p>//IR always @(posedge Clock) if (init)IR<= #20 0; else begin if( ((IR[13:8] == `INCFSZ)&&(Z==1)) || ((IR[13:8] == `DECFSZ)&&(Z==1))|| ((IR[13:10] == `BTFSC) &&(Z==1))|| ((IR[13:10] == `BTFSS) &&(Z==0))|| (IR[13:11] == `GOTO)|| (IR[13:0] == `RETURN)|| (IR[13:0] == `RETFIE)|| (IR[13:10] == `RETLW)|| (IR[13:11] == `CALL) ) IR <= #20 0;//NOP else IR <= #20 inext;//i is Data_rom from ROM or ramd from SRAM end</p><p>//PC always @(posedge Clock) if (init) begin pcl<=0;//PC starts with 00 instruction pclath<=0;//PC starts with 00 instruction PC1<=0; PC2<=0; PC3<=0; PC4<=0; PC5<=0; PC6<=0; PC7<=0; PC8<=0; end else begin //load pcl if ((loadf)&&(pcl_en)) pcl <= To_File ;</p><p>//load pch else if ((loadf)&&(pch_en)) pclath <= To_File ; else if(IR[13:11] == `GOTO) begin pcl<= IR[7:0]; pclath<= IR[10:8];//4th ,3rd bit of pclath are upper bits for the PC end else if(IR[13:11] == `CALL) begin PC1<= {pclath[4:3], IR[10:0]};//FIFO PC2<= PC1; PC3<= PC2; PC4<= PC3; PC5<= PC4; PC6<= PC5; PC7<= PC6; PC8<= PC7; end</p><p> else if ((IR[13:0] == `RETURN)||(IR[13:0] == `RETFIE)||(IR[13:10] == `RETLW)) begin if (IR[13:0] == `RETLW) W<=IR[7:0]; {pclath[4:0], pcl} <= PC1; PC1<= PC2; //FIFO PC2<= PC3; PC3<= PC4; PC4<= PC5; PC5<= PC6; PC6<= PC7; PC7<= PC8; end else begin {pclath[4:0], pcl} <= {pclath[4:0], pcl} + 1;//increment PC //if (pcl==8'b11111111) pclath[4:0]<=pclath[4:0] +1; end end endmodule ///////////////////////////////////////////////////////////////////////// // PIC 16F84 // ALU - Designed by Troendle PP under Iain Mc Nally // // ALU Bit: // // // // // // // Southampton University - Department of ECS ///////////////////////////////////////////////////////////////////////// `include "opcodes.v" `timescale 100ps / 10 ps module alu( ALU_output, A, M, Function);</p><p>//I/O connection output[7:0] ALU_output; input [7:0] A, M; input [6:0] Function;</p><p>//register reg [7:0] ALU_output;</p><p>//======ALU + ACC======always @(A or M or Function)begin casex (Function[6:1]) `ADDWF : ALU_output <= M + A; `ADDLW : ALU_output <= M + A; `INCFSZ : ALU_output <= M + 1; `INCF : ALU_output <= M + 1; `MOVWF : ALU_output <= A ; `SUBWF : ALU_output <= M - A; `SUBLW : ALU_output <= M - A; `DECFSZ : ALU_output <= M - 1; `DECF : ALU_output <= M - 1; `ANDWF : ALU_output <= M & A; `ANDLW : ALU_output <= M & A; `IORWF : ALU_output <= A | M; `IORLW : ALU_output <= A | M; `SWAPF : begin ALU_output[7:4] <= M[3:0]; ALU_output[3:0] <= M[7:4]; end `RLF : ALU_output <= M << 1; `RRF : ALU_output <= M >> 1; `XORWF : ALU_output <= M ^ A; `XORLW : ALU_output <= M ^ A; `COMF : ALU_output <= M ^ 8'b11111111; `BCFX: begin if (Function[2:0]==3'b000) ALU_output <= M & 8'b11111110; if (Function[2:0]==3'b001) ALU_output <= M & 8'b11111101; if (Function[2:0]==3'b010) ALU_output <= M & 8'b11111011; if (Function[2:0]==3'b011) ALU_output <= M & 8'b11110111; if (Function[2:0]==3'b100) ALU_output <= M & 8'b11101111; if (Function[2:0]==3'b101) ALU_output <= M & 8'b11011111; if (Function[2:0]==3'b110) ALU_output <= M & 8'b10111111; if (Function[2:0]==3'b111) ALU_output <= M & 8'b01111111; end `BSFX : begin if (Function[2:0]==3'b000) ALU_output <= M | 8'b00000001; if (Function[2:0]==3'b001) ALU_output <= M | 8'b00000010; if (Function[2:0]==3'b010) ALU_output <= M | 8'b00000100; if (Function[2:0]==3'b011) ALU_output <= M | 8'b00001000; if (Function[2:0]==3'b100) ALU_output <= M | 8'b00010000; if (Function[2:0]==3'b101) ALU_output <= M | 8'b00100000; if (Function[2:0]==3'b110) ALU_output <= M | 8'b01000000; if (Function[2:0]==3'b111) ALU_output <= M | 8'b10000000; end `BTFSCX, `BTFSSX : begin if (Function[2:0]==3'b000) ALU_output <= M & 8'b00000001; if (Function[2:0]==3'b001) ALU_output <= M & 8'b00000010; if (Function[2:0]==3'b010) ALU_output <= M & 8'b00000100; if (Function[2:0]==3'b011) ALU_output <= M & 8'b00001000; if (Function[2:0]==3'b100) ALU_output <= M & 8'b00010000; if (Function[2:0]==3'b101) ALU_output <= M & 8'b00100000; if (Function[2:0]==3'b110) ALU_output <= M & 8'b01000000; if (Function[2:0]==3'b111) ALU_output <= M & 8'b10000000; end `CLRF : ALU_output <= 0 ; //works for CLRW default : ALU_output <= M; endcase end endmodule //////////////////////////////////////////////////////////////////////// // PIC 16F84 // RAM - Designed by PP Troendle under Iain Mc Nally // // ram module (68 bytes) // 256 words.0Ch-4Fh <= 8Ch-CFh //(50h-7Fh D0h-FFh unimplemented, read as '0') // // // // Southampton University - Department of ECS ///////////////////////////////////////////////////////////////////////// `timescale 100ps / 10ps module ram(Clock, WnR, Address_File, Data_in, data_out);</p><p>//I/O connections input Clock, WnR; input [7:0] Data_in; input [7:0] Address_File; output [7:0] data_out;</p><p>//register reg [7:0] Data_stored [127:0];</p><p>//wire wire [7:0] data_out; wire [7:0] Address_File; wire [7:0] Data_in; wire WnR;</p><p>//the double address registers //folding addresses > 'h80 into 127 bytes: 7 lower bits considered only assign data_out[7:0] = Data_stored[{1'b0,(Address_File[6:0])}]; always @(posedge Clock) if (WnR) Data_stored[{1'b0,(Address_File[6:0])}] <= Data_in[7:0]; endmodule ///////////////////////////////////////////////////////////////////////// //======// PORT // PORT - Designed by PP Troendle under Iain Mc Nally // // // ////////////////////////////////////////////////////////////////////////// `timescale 100ps / 10ps</p><p>// behavioural model of a port module port(Clock, init, port, From_File, To_File, loadf, tr_en, po_en); inout [7:0] port; output [7:0] From_File; input [7:0] To_File; input Clock, init; input loadf, tr_en, po_en; wire [7:0] port; wire [7:0] From_File; wire [7:0] To_File; wire [7:0] port_in; wire Clock, init; wire loadf, tr_en, po_en; reg [7:0] port_out; reg [7:0] tris; assign port[0] = (tris[0] == 0)? port_out[0] : 1'bz; assign port[1] = (tris[1] == 0)? port_out[1] : 1'bz; assign port[2] = (tris[2] == 0)? port_out[2] : 1'bz; assign port[3] = (tris[3] == 0)? port_out[3] : 1'bz; assign port[4] = (tris[4] == 0)? port_out[4] : 1'bz; assign port[5] = (tris[5] == 0)? port_out[5] : 1'bz; assign port[6] = (tris[6] == 0)? port_out[6] : 1'bz; assign port[7] = (tris[7] == 0)? port_out[7] : 1'bz; assign port_in = port; assign From_File= (tr_en)? tris :(po_en)? port_in : 8'bz; always @(posedge Clock) if (init) begin port_out<=0; tris<=8'b11111111; //as outputs they may try and drive a switch!! end else begin if (loadf) begin if (tr_en) tris <= To_File; if (po_en) port_out <= To_File; end end endmodule ///////////////////////////////////////////////////////////////////////// //======// PIC 16F84 // LCD BUF - Designed by PP Troendle under Iain Mc Nally // // lcd buffer module // 256 words.0-255 // // ////////////////////////////////////////////////////////////////////////// `timescale 100ps / 10 ps module lcd (Debug, DBus, phase, addr, instr, lcdd, lcde , lcdr_w, lcdrs, n_reset, Clock, cstep_en, c20_en, progselect, download, init);</p><p>//From_File, To_File</p><p>// I/O declarations input Debug, init; output [7:0]lcdd; output lcde, lcdr_w, lcdrs; input Clock, n_reset, download; input [1:0] progselect; input cstep_en, c20_en; input [13:0] instr; input [12:0] addr; input [7:0] DBus; input [1:0] phase;</p><p>//registers reg [7:0] lcdd; reg lcde; reg lcdrs; reg [5:0] count; reg [1:0] lcdecount;</p><p>//wires wire Debug, init; wire lcdr_w; //constant = 0 wire cstep_en, c20_en, Clock, n_reset; wire [1:0] progselect; wire [1:0] phase; wire lcdclock; wire [13:0] instr; wire [12:0] addr; wire [7:0] DBus; wire download; assign lcdr_w = 0; //no read required 40us wait is good enough instead of wait the busy flag always @ (posedge Clock or negedge n_reset) if (!n_reset) begin lcdecount <=0; lcdd <=0; lcdrs <=0; //Command count <=0; lcde <=0; end else begin lcdecount<=lcdecount+1; case (lcdecount) 0 : begin lcde <=0; count <=count+1; case (count) //rs low = Command 0 : begin lcdrs <= 0; lcdd <= 'h 38; //Format //8 bits 1 line 5*7 end 1 : lcdd<= 'h 08; //On/off //Display, cursor,blink off 2 : lcdd<= 'h 0C; //enable display nort cusor not blink 3 : lcdd<= 'h 06; //shift mode //auto inc 4 : lcdd<= 'h 80; //Position // start write of display char 0</p><p>//rs high = DATA 5 : begin lcdrs<=1; lcdd<= LCDascii(0); end 6 : lcdd<= LCDascii(1); 7 : lcdd<= LCDascii(2); 8 : lcdd<= LCDascii(3); 9 : lcdd<= LCDascii(4); 10 :lcdd<= LCDascii(5); 11 :lcdd<= LCDascii(6); 12 :lcdd<= LCDascii(7);</p><p>//rs low = Command 13 : begin lcdrs<=0; lcdd<= 'h C0; //line 2 position end</p><p>//rs high = DATA 14 : begin lcdrs<=1; lcdd<= LCDascii(8); end 15 :lcdd<= LCDascii(9); 16 :lcdd<= LCDascii(10); 17 :lcdd<= LCDascii(11); 18 :lcdd<= LCDascii(12); 19 :lcdd<= LCDascii(13); 20 :lcdd<= LCDascii(14); 21 :lcdd<= LCDascii(15);</p><p>//rs low = command 22 : begin lcdrs<= 0; lcdd<= 'h 80; //Position // start write of display char 0 count<= 5; end endcase end 2 : lcde <=1; default : lcde <=0; endcase end function [7:0] LCDascii; input [3:0] whichChar; if (download) // Downloading LCDascii = Download2ascii(whichChar); else if (init) LCDascii = Init2ascii(whichChar); else if (Debug) // Debug info (pc, inst, from file, to file) LCDascii = Debug2ascii(whichChar); else if (whichChar > 5) LCDascii = Prog2ascii(whichChar); //Prog 1,2,3,4 else if (c20_en) // 20 MHz LCDascii = Fast2ascii(whichChar); else if (cstep_en) // Step LCDascii = Step2ascii(whichChar); else // Slow LCDascii = Slow2ascii(whichChar); endfunction</p><p> function [7:0] num2ascii; input [3:0] num; if (num < 10) num2ascii = 8'h30 + num; else num2ascii = 8'h37 + num; endfunction</p><p> function [7:0] Download2ascii; input [3:0] whichChar; case (whichChar) 0: Download2ascii = "D"; 1: Download2ascii = "o"; 2: Download2ascii = "w"; 3: Download2ascii = "n"; 4: Download2ascii = "l"; 5: Download2ascii = "o"; 6: Download2ascii = "a"; 7: Download2ascii = "d"; 8: Download2ascii = "i"; 9: Download2ascii = "n"; 10: Download2ascii = "g"; default: Download2ascii = " "; endcase endfunction</p><p> function [7:0] Init2ascii; input [3:0] whichChar; case (whichChar) 0: Init2ascii = "I"; 1: Init2ascii = "n"; 2: Init2ascii = "i"; 3: Init2ascii = "t"; default: Init2ascii = " "; endcase endfunction</p><p> function [7:0] Debug2ascii; input [3:0] whichChar; case (whichChar) 0: Debug2ascii = num2ascii(addr[11:8]); 1: Debug2ascii = num2ascii(addr[7:4]); 2: Debug2ascii = num2ascii(addr[3:0]);</p><p>4: Debug2ascii = num2ascii({2'b00,instr[13:12]}); 5: Debug2ascii = num2ascii(instr[11:8]); 6: Debug2ascii = num2ascii(instr[7:4]); 7: Debug2ascii = num2ascii(instr[3:0]);</p><p>9: Debug2ascii = num2ascii({2'b00, phase}+1);</p><p>11: Debug2ascii = Info2ascii(whichChar); 12: Debug2ascii = Info2ascii(whichChar); 14: Debug2ascii = (phase == 0) ? " " : num2ascii(DBus[7:4]); 15: Debug2ascii = (phase == 0) ? " " : num2ascii(DBus[3:0]); default: Debug2ascii = " "; endcase endfunction function [7:0] Info2ascii; input [3:0] whichChar; case (phase) 0: Info2ascii = Decode2ascii(whichChar); 1: Info2ascii = Execute2ascii(whichChar); 2: Info2ascii = Write12ascii(whichChar); 3: Info2ascii = Write22ascii(whichChar); endcase endfunction function [7:0] Decode2ascii; input [3:0] whichChar; case (whichChar) 11: Decode2ascii = "D"; 12: Decode2ascii = "E"; default: Decode2ascii = " "; endcase endfunction function [7:0] Execute2ascii; input [3:0] whichChar; case (whichChar) 11: Execute2ascii = "E"; 12: Execute2ascii = "X"; default: Execute2ascii = " "; endcase endfunction function [7:0] Write12ascii; input [3:0] whichChar; case (whichChar) 11: Write12ascii = "W"; 12: Write12ascii = "1"; default: Write12ascii = " "; endcase endfunction function [7:0] Write22ascii; input [3:0] whichChar; case (whichChar) 11: Write22ascii = "W"; 12: Write22ascii = "2"; default: Write22ascii = " "; endcase endfunction function [7:0] Prog2ascii; input [3:0] whichChar; case (whichChar) 7: Prog2ascii = "P"; 8: Prog2ascii = "r"; 9: Prog2ascii = "o"; 10: Prog2ascii = "g"; 12: Prog2ascii = num2ascii(4'b0100-{2'b00,progselect}); default: Prog2ascii = " "; endcase endfunction function [7:0] Fast2ascii; input [3:0] whichChar; case (whichChar) 0: Fast2ascii = "2"; 1: Fast2ascii = "0"; 2: Fast2ascii = " "; 3: Fast2ascii = "M"; 4: Fast2ascii = "H"; 5: Fast2ascii = "z"; default: Fast2ascii = " "; endcase endfunction</p><p> function [7:0] Slow2ascii; input [3:0] whichChar; case (whichChar) 0: Slow2ascii = "S"; 1: Slow2ascii = "l"; 2: Slow2ascii = "o"; 3: Slow2ascii = "w"; default: Slow2ascii = " "; endcase endfunction</p><p> function [7:0]Step2ascii; input [3:0] whichChar; case (whichChar) 0: Step2ascii = "S"; 1: Step2ascii = "t"; 2: Step2ascii = "e"; 3: Step2ascii = "p"; default: Step2ascii = " "; endcase endfunction endmodule ///////////////////////////////////////////////////////////////////////// //======// PIC 16F84 // MASTER CONTROL - Designed by PP Troendle under Iain Mc Nally // // master control // ////////////////////////////////////////////////////////////////////////// `timescale 100ps / 10 ps module mc(ck_20mhz, sstep_r, sstep_s, n_reset, clksel, spare, prog, progselect, init, picClock, phase, lcdClock, download, cstep_en, c20_en);</p><p>// I/O declarations output init, picClock, lcdClock; output cstep_en, c20_en, download; input [1:0] clksel, prog; output [1:0] progselect; output [1:0] phase; input spare, n_reset, ck_20mhz, sstep_r, sstep_s;</p><p>//wires wire [1:0] clksel, prog; wire spare, n_reset, ck_20mhz, ck_10mhz, sstep_r, sstep_s; wire slowClock, lcdClock; wire init;</p><p>//Registers reg cstep_en, c20_en, picClock; reg [1:0] phase; reg clkevent, slowclkevent, oldSlowClock, stepClock; reg [1:0] progselect; reg pic_running; reg [1:0] progretime; reg download;</p><p>//clocks clock clock1(ck_20mhz, ck_10mhz, slowClock, lcdClock, n_reset); always @ (posedge ck_10mhz or negedge n_reset) if ( !n_reset ) begin oldSlowClock = 0; slowclkevent = 0; end else begin // slow clock if (( slowClock == 1 ) && ( oldSlowClock == 0 )) slowclkevent = 1; else slowclkevent = 0;</p><p> oldSlowClock = slowClock; end always @ (posedge ck_10mhz or negedge n_reset) if ( !n_reset ) begin stepClock = 0; clkevent = 0; end else begin</p><p> if ( slowclkevent )</p><p> if ( clksel == 3 ) // step Clock begin if ( ! sstep_r ) begin clkevent = 0; stepClock = 0; end else if ( ! sstep_s ) begin if ( stepClock == 0 ) clkevent = 1; else clkevent = 0; stepClock = 1; end end else clkevent = 1; else clkevent = 0;</p><p> end always @ (posedge ck_10mhz or negedge n_reset) if ( !n_reset ) begin picClock = 1; phase = 0; end else begin if (clksel == 0) // 5 MHz begin picClock = ! picClock; end else // slow or stepped clock - provide phase info to LCD if ( clkevent ) begin phase = phase + 1; picClock = ! phase[1]; end end always @ (posedge ck_10mhz)// retime asynchronous signals begin cstep_en <= (clksel == 2'b11); c20_en <= (clksel == 2'b00); progretime <= prog; download <= !spare;///////////// end always @ (posedge picClock or negedge n_reset)//////////////// if ( !n_reset ) begin progselect = 0; pic_running = 0; end else begin //initiates a reset after a control switch is been changed progselect = progretime; pic_running = 1; end assign init = !pic_running || ( progselect != progretime ) || download; endmodule /////////////////////////////////////////////////////////////////////////// // PIC 16F84 // clock - Designed by PP Troendle under Iain Mc Nally // // clock module // // Southampton University - Department of ECS ///////////////////////////////////////////////////////////////////////// `timescale 100ps / 10ps</p><p>// behavioural model of a clock module module clock(ck_20mhz, ck_10mhz, slowClock, lcdClock, n_reset); output ck_10mhz, slowClock, lcdClock; input ck_20mhz, n_reset; wire ck_10mhz, ck_20mhz, slowClock, lcdClock, n_reset; reg [19:0] div; assign ck_10mhz = div[1]; assign lcdClock = div[10]; assign slowClock = div[19]; always @(posedge ck_20mhz or negedge n_reset) if (!n_reset) div<=0; else div <= div + 1; endmodule ///////////////////////////////////////////////////////////////////////// //======// PIC 16F84 // Single Instruction - Designed by PP Troendle under Iain Mc Nally // // prog_single_inst module // // 256 words.0-255 // /////////////////////////////////////////////////////////////////////// `timescale 100ps / 10ps module prog_single_inst(Data_rom);</p><p>//I/O connections output [13:0] Data_rom;</p><p>//wire wire [13:0] Data_rom; assign Data_rom = 'h 0390; endmodule ///////////////////////////////////////////////////////////////////////// //======// PIC 16F84 // Simple Program - Designed by PP Troendle under Iain Mc Nally // // prog_simple module // // 256 words.0-255 // /////////////////////////////////////////////////////////////////////// `timescale 100ps / 10ps module prog_simple(Data_rom, Address_rom);</p><p>//I/O connections output [13:0] Data_rom; input [12:0] Address_rom; //1K</p><p>//register reg [13:0] Data_rom;</p><p>//wire wire [12:0] Address_rom; always @(Address_rom) begin // 00001 LIST P=16F84 // 00002 INCLUDE “P16F84.INC” ;Full set of definitions //2007 3FF1 00003 __CONFIG CPOFF & PWRTEOFF & WDT_OFF & _XT_OSC //0000 00004 ORG 0 ; Reset vector if (Address_rom==0) Data_rom<= 'h2805; //GOTO INIT //0000 2805 00005 GOTO INIT else if (Address_rom==1) Data_rom<= 'h0000; //0001 0000 00006 NOP else if (Address_rom==2) Data_rom<= 'h0000; //0002 0000 00007 NOP else if (Address_rom==3) Data_rom<= 'h0000; //0003 0000 00008 NOP else if (Address_rom==4) Data_rom<= 'h0000; //0004 0000 00009 NOP //0005 00010 ORG 5 ; One past interrupt vector //0005 00011 INIT else if (Address_rom==5) Data_rom<= 'h30FF; //MOWLW 0xxFF //0005 30FF 00012 MOVLW 0xFF else if (Address_rom==6) Data_rom<= 'h0065; //MOWLW 0xxFF //0006 0065 00013 TRIS PORTA ; All input else if (Address_rom==7) Data_rom<= 'h0103; //MOWLW 0xxFF //0007 0103 00014 CLRW else if (Address_rom==8) Data_rom<= 'h0066; //MOWLW 0xxFF //0008 0066 00015 TRIS PORTB ; All output //0009 00016 FOREVER ; Main programm loop else if (Address_rom==9) Data_rom<= 'h0805; //MOWLW 0xxFF //0009 0805 00017 MOVF PORTA, W ; Get input else if (Address_rom==10) Data_rom<= 'h0086; //MOWLW 0xxFF //000A 0086 00018 MOWF PORTB ; Copy to output else if (Address_rom==11) Data_rom<= 'h2809; //MOWLW 0xxFF //000B 2809 00019 GOTO FOREVER else if (Address_rom==12) Data_rom<= 'h0000; //000C 0000 00020 NOP ; Redundant fetch // 00021 END else Data_rom <= 0; end endmodule /////////////////////////////////////////////////////////////////////////// ////======//// PIC 16F84 //// PROG 3 - Designed by PP Troendle under Iain Mc Nally //// //// prog_complex module //// //// 256 words.0-255 //// ///////////////////////////////////////////////////////////////////////// `timescale 100ps / 10ps module prog_complex(Data_rom, Address_rom);</p><p>//I/O connections output [13:0] Data_rom; input [12:0] Address_rom; //1K</p><p>//register reg [13:0] Data_rom; //wire wire [12:0] Address_rom; always @(Address_rom) begin //ROM in combinational form //0000 3000 00001 MOVLW 00 if (Address_rom==0) Data_rom<='h 3000; //0001 008A 00002 MOVWF 0A else if (Address_rom==1) Data_rom<='h 008A; //0002 2804 00003 GOTO 004 else if (Address_rom==2) Data_rom<='h 2804; //0003 0000 00004 NOP else if (Address_rom==3) Data_rom<='h 0000; //0000 00005 ...... #include <16F84.h> //0000 00006 ...... //////// Standard Header file for the PIC16F84 device //////// //0000 00007 ...... #device PIC16F84 //0000 00077 ...... #list //0000 00078 ...... //0000 00079 ...... #use Delay(Clock=2000000) //0000 00080 ...... #byte portB = 6 //0000 00081 ...... #fuses HS,NOWDT,NOPROTECT //0000 00082 ...... //0000 00083 ...... //0000 00084 ...... void main(void) { //0000 00085 ...... char count; //0000 00086 ...... char last_clock, clock,tmp; //0004 0184 00087 CLRF 04 else if (Address_rom==4) Data_rom<='h 0184; //0005 301F 00088 MOVLW 1F else if (Address_rom==5) Data_rom<='h 301F; //0006 0583 00089 ANDWF 03,F else if (Address_rom==6) Data_rom<='h 0583; //0000 00090 ...... count=0; //0007 018F 00091 CLRF 0F else if (Address_rom==7) Data_rom<='h 018F; //0000 00092 ...... SET_TRIS_B(0x00); //0008 3000 00093 MOVLW 00 else if (Address_rom==8) Data_rom<='h 3000; //0009 0066 00094 TRIS 6 else if (Address_rom==9) Data_rom<='h 0066; //0000 00095 ...... last_clock=input(PIN_A0); //000A 1683 00096 BSF 03,5 else if (Address_rom==10) Data_rom<='h 1683; //000B 1405 00097 BSF 05,0 else if (Address_rom==11) Data_rom<='h 1405; //000C 1283 00098 BCF 03,5 else if (Address_rom==12) Data_rom<='h 1283; //000D 0190 00099 CLRF 10 else if (Address_rom==13) Data_rom<='h 0190; //000E 1805 00100 BTFSC 05,0 else if (Address_rom==14) Data_rom<='h 1805; //000F 0A90 00101 INCF 10,F else if (Address_rom==15) Data_rom<='h 0A90; //0000 00102 ...... //0000 00103 ...... //0000 00104 ...... while(TRUE) { //0000 00105 ...... clock=input(PIN_A0); //0010 1683 00106 BSF 03,5 else if (Address_rom==16) Data_rom<='h 1683; //0011 1405 00107 BSF 05,0 else if (Address_rom==17) Data_rom<='h 1405; //0012 1283 00108 BCF 03,5 else if (Address_rom==18) Data_rom<='h 1283; //0013 0191 00109 CLRF 11 else if (Address_rom==19) Data_rom<='h 0191; //0014 1805 00110 BTFSC 05,0 else if (Address_rom==20) Data_rom<='h 1805; //0015 0A91 00111 INCF 11,F else if (Address_rom==21) Data_rom<='h 0A91; //0000 00112 ...... clock&= 0x01; //0016 3001 00113 MOVLW 01 else if (Address_rom==22) Data_rom<='h 3001; //0017 0591 00114 ANDWF 11,F else if (Address_rom==23) Data_rom<='h 0591; //0000 00115 ...... tmp = clock - last_clock; //0018 0811 00116 MOVF 11,W else if (Address_rom==24) Data_rom<='h 0811; //0019 0092 00117 MOVWF 12 else if (Address_rom==25) Data_rom<='h 0092; //001A 0810 00118 MOVF 10,W else if (Address_rom==26) Data_rom<='h 0810; //001B 0292 00119 SUBWF 12,F else if (Address_rom==27) Data_rom<='h 0292; //0000 00120 ...... if(tmp==0)continue; //001C 0892 00121 MOVF 12,F else if (Address_rom==28) Data_rom<='h 0892; //001D 1D03 00122 BTFSS 03,2 else if (Address_rom==29) Data_rom<='h 1D03; //001E 2820 00123 GOTO 020 else if (Address_rom==30) Data_rom<='h 2820; //001F 2810 00124 GOTO 010 else if (Address_rom==31) Data_rom<='h 2810; //0000 00125 ...... last_clock=clock; //0020 0811 00126 MOVF 11,W else if (Address_rom==32) Data_rom<='h 0811; //0021 0090 00127 MOVWF 10 else if (Address_rom==33)Data_rom<='h 0090; //0000 00128 ...... //0000 00129 ...... if(clock==1) count++; //0022 3001 00130 MOVLW 01 else if (Address_rom==34) Data_rom<='h 3001; //0023 0211 00131 SUBWF 11,W else if (Address_rom==35) Data_rom<='h 0211; //0024 1D03 00132 BTFSS 03,2 else if (Address_rom==36) Data_rom<='h 1D03; //0025 2827 00133 GOTO 027 else if (Address_rom==37) Data_rom<='h 2827; //0026 0A8F 00134 INCF 0F,F else if (Address_rom==38) Data_rom<='h 0A8F; //0000 00135 ...... portB=count; //0027 080F 00136 MOVF 0F,W else if (Address_rom==39) Data_rom<='h 080F; //0028 0086 00137 MOVWF 06 else if (Address_rom==40) Data_rom<='h 0086; //0000 00138 ...... } //0029 2810 00139 GOTO 010 else if (Address_rom==41) Data_rom<='h 2810; //0000 00140 ...... //0000 00141 ...... } //002A 0063 0142 SLEEP else Data_rom <= 0; end endmodule ///////////////////////////////////////////////////////////////////////// //======// PIC 16F84 // SRAM BUFFER- Designed by PP Troendle under Iain Mc Nally // // the sram buffer module // 256 words.0-255 // // Data shifted in from spin into spaddr or spdata according to spit // addr increment when completed at spit = 01 : ready for write ////////////////////////////////////////////////////////////////////////// `timescale 100ps / 10 ps module srambuff(n_reset, Clock, n_ramoe, n_ramwe, spin, spit, sick, ramd, a, download, PC);</p><p>// I/O declarations inout [15:0] ramd; output [15:0] a; input [12:0] PC; input n_reset, download; input Clock; input spin; input [1:0] spit; input sick; output n_ramoe; output n_ramwe;</p><p>//registers reg [15:0] spdata, spaddr; reg sick0, sick1, spin_in;</p><p>//wires wire [15:0] ramd, a; wire [12:0] PC; wire [15:0] data_ser; wire [15:0] addr_ser; wire n_reset; wire Clock; wire spin; wire [1:0] spit; wire sick; wire download; wire n_ramoe; wire n_ramwe;</p><p>//address and data sram assign ramd = (download) ? data_ser : 16'bz; //data to SRAM assign a = (download) ? addr_ser : {3'b000,PC}; //address to SRAM assign n_ramoe = download; //disable read from SRAM assign n_ramwe = !( sick && (spit == 2'b01)); //enable write to SRAM assign data_ser = spdata; assign addr_ser = spaddr + 1; //********problem with spec?****** always @ (posedge Clock or negedge n_reset) if (!n_reset) begin sick1 <= 0; sick0 <= 0; end else begin sick1 <= sick; sick0 <= sick1; end always @ (posedge sick0 or negedge n_reset) // capture spin on rising edge of sick if (!n_reset) begin spin_in <= 0; end else begin spin_in <= spin; end always @ (negedge sick0 or negedge n_reset) // update spdata, spaddr on falling edge of clock if (!n_reset) begin spdata <= 0; spaddr <= 0; end else begin case (spit) 2'b00: spaddr <= {spin_in, spaddr[15:1]}; //serial shifting the address -1 in 2'b10: spdata <= {spin_in, spdata[15:1]}; 2'b01: spaddr <= spaddr + 1; //post increment as required by spec 2'b11: ; endcase end endmodule //======// PIC 16F84 // System on Chip - Designed by PP Troendle under Iain Mc Nally // // // // // // Southampton University - Department of ECS //======</p><p>`include "opcodes.v" `timescale 100ps / 10 ps module system_chip(lcdd, lcde, lcdrs, lcdr_w, spare, a , ramd, n_ramoe, n_ramwe, ck_20mhz, n_reset, porta, portb, sstep_r, sstep_s, clksel, sick, spin, spit, prog, i, d);</p><p>// I/O declarations output [15:0] a; // address fot external SRAM output [13:0] i; output [7:0] d; inout [7:0] porta, portb; // PIC I/O inout [15:0] ramd; // databus fot external SRAM output n_ramoe, n_ramwe; // control for external SRAM output [7:0] lcdd; // LCD output lcde, lcdrs, lcdr_w; // LCD input sick, spin, spare; // serial programming clock, data and enable input [1:0] spit; // serial programming control input [1:0] prog; // programm select (SRAM, ROM) input sstep_r, sstep_s; // single step button input [1:0] clksel; // clock speed select input ck_20mhz; // Clocks input n_reset; // Reset</p><p>// wires wire [7:0] porta, portb; // PIC I/O wire [15:0] a; // address fot external SRAM wire [13:0] i; wire [7:0] d; wire [12:0] PC; wire [13:0] inext; // next instruction wire [13:0] IR; // current instruction wire [13:0] Data_rom1, Data_rom2, Data_rom3; wire [15:0] ramd; // databus fot external SRAM wire n_ramoe, n_ramwe; // control for external SRAM wire sram_w; // send the data to the SRAM wire sick, spin, spare; // serial programming clock, data and enable wire [1:0] spit; // serial programming control wire [15:0] addr_ser; // from the serial input wire [15:0] data_ser; // from the serial input wire [1:0] prog; // programm select (SRAM, ROM) wire download, cstep_en, c20_en;// LCD wire [7:0] lcdd; // LCD wire lcde, lcdrs, lcdr_w; // LCD wire [7:0] M, To_File; // LCD wire sstep_r, sstep_s; // single step button wire [1:0] clksel, phase; // clock speed select wire ck_20mhz, picClock, lcdclock; // Clocks wire init, n_reset; // Reset wire Debug; wire [1:0] progselect; assign i = IR; assign d = (picClock==1) ? M : To_File; // ALU input in first part of clock cycle // ALU output in second part of clock cycle mc mc1(ck_20mhz, sstep_r, sstep_s, n_reset, clksel, spare, prog, progselect, init, picClock, phase, lcdclock, download, cstep_en, c20_en); lcd lcd1(Debug, d, phase, PC, IR, lcdd, lcde, lcdr_w, lcdrs, n_reset, lcdclock, cstep_en, c20_en, progselect, download, init); assign Debug = ! c20_en; //LCD with Debug information chosen pic pic1(PC, inext, picClock, init, porta, portb, M, To_File, IR);</p><p>//sram or rom select assign inext = (progselect ==`PROG1SEL) ? Data_rom1 : (progselect ==`PROG2SEL) ? Data_rom2 : (progselect ==`PROG3SEL) ? Data_rom3 : ramd[13:0]; //IR data from SRAM or ROM</p><p>//programm memory prog_single_inst prog1(Data_rom1); prog_simple prog2(Data_rom2, PC); prog_complex prog3(Data_rom3, PC);</p><p>//progamming sram srambuff srambuff1(n_reset, ck_20mhz, n_ramoe, n_ramwe, spin, spit, sick, ramd, a, download, PC); endmodule</p>
Details
-
File Typepdf
-
Upload Time-
-
Content LanguagesEnglish
-
Upload UserAnonymous/Not logged-in
-
File Pages19 Page
-
File Size-