PIC - Designed by PP Troendle Under Iain Mc Nally

PIC - Designed by PP Troendle Under Iain Mc Nally

<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>

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    19 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us