NPL Tutorial - Step 4
Verilog Source
Before proceeding, it might be a good idea to understand, what the new CPLD programming file will do to our Ethernut Board. For this we will now present the most incomplete introduction to Verilog HDL. ;-)
Verilog is very similar to the C programming language. A Verilog source consists of one or more modules, which can be called like C functions from within other modules. Our sample provides one module only:
module npltut01(NRESET, NMR, A, D, D15, P3, P4, P5, P6, P7, P8, P9, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, NOE, NWE, NCS0, NWAIT, NFBYTE, CAR, CDR, NCRD, NCWR, PNCS, CRD, CTD, CRTS, CCTS, CDTR, CDSR, CDCD, CRI, CFON, CNFOFF, CNINVAL, MDAT, MCLK, MCMD, MCD, MWP, ALARM, PLCLK1, PLCLK2, CLKS2, CLKOE, ULED, WAKEUP, FBUSY);
input NRESET; input NMR; input [23:0]A; inout [7:0]D; input D15; input P3; input P4; input P5; input P6; input P7; input P8; input P9; input P12; input P13; input P14; output P15; input P16; input P17; input P18; input P19; input P20; input P21; input P22; input P23; input P24; input P25; input P26; input P27; input NOE; input NWE; input NCS0; output NWAIT; output [15:0]CAR; inout [7:0]CDR; output NCRD; output NCWR; output PNCS; input CRD; output CTD; input CCTS; output CRTS; input CDSR; output CDTR; input CDCD; input CRI; input CNINVAL; output CFON; output CNFOFF; inout [3:0]MDAT; output MCLK; output MCMD; input MCD; input MWP; input ALARM; input WAKEUP; input PLCLK1; input PLCLK2; output CLKS2; output CLKOE; output ULED; input FBUSY; output NFBYTE;
The following part of our module specifies the behaviour of the CPLD. In this simple module we use assignments only. Furthermore we will ignore most input signal, which produced the warnings in our previous step.
The first assign statement sets the data bus to Z-State. For those of you who are not too familiar with hardware: This is a high impedance state of an output. It means, that the output is neither low nor high and doesn't influence the connected signals in any way. More simple, these are switched-off outputs.
assign D = 8'bzzzzzzzz;
inout [7:0]D;
assign D = 8'b00000000; // Do not do this!
// Never ever do this! assign D[0] = 1'b1; assign D[1] = 1'b1; assign D[2] = 1'b1; assign D[3] = 1'b1; assign D[4] = 1'b1; assign D[5] = 1'b1; assign D[6] = 1'b1; assign D[7] = 1'b1;
We also switch off the NWAIT output. This can be used to delay CPU access times for slow devices, which we do not need here.
assign NWAIT = 1'bz;
While looking to the schematics, you may have noticed, that the address and data busses of the Ethernut expansion port are not directly connected to the CPU, but to the CPLD instead. This has two advantages. First the busses can be made compatible to the previous AVR based Ethernut versions. Second they can be used for different functions like I/O Ports, if no external memory bus is required. In out sample we set all lines to fixed levels.
assign CAR = 16'b0; assign CDR = 8'b0; assign NCRD = 1'b1; assign NCWR = 1'b1; assign PNCS = 1'b1;
A very special feature of Ethernut 3 is, that the complete RS232 interface is controlled by the CPLD. Sooner or later this will drive you crazy while experimenting with the CPLD. Doing something wrong may result in losing the RS232 output, leaving you completely in the dark. We will do it right here and connect the CPU lines for UART receive and transmit to the right RS232 lines.
assign P15 = CRD; assign CTD = P14;
The rest of our sample module doesn't present anything new. The RS232 handshake signals
assign CRTS = 1'b0; assign CDTR = 1'b0; assign CFON = 1'b1; assign CNFOFF = 1'b1;
assign MDAT = 4'b0000; assign MCLK = 1'b0; assign MCMD = 1'b0;
The CLKS2 output selects the CPU main clock. If high, the CPU is running at full speed. Setting the CLKOE line to low would have the effect of switching all clocks off. This would be the most desastrous thing we could do and will completely disable the Ethernut. So better set it high.
assign CLKS2 = 1'b1; assign CLKOE = 1'b1;
The next output controls the green User LED, which is integrated in the reset button. Setting this line low will switch the LED on.
assign ULED = 1'b0;
Finally the NFBYTE signal controls the mode of the Flash Memory Chip, the one that contains the bootloader, for example. The CPU expects this chip in 16-bit mode, so we have to set this output to high.
assign NFBYTE = 1'b1;
That's all our Verilog sample does. In summary, it switches on the User LED and routes UART0 to the RS232 interface. Most important, it will not disturb the basic functions of our Ethernut 3 board, so we will be able to replace the CPLD functions later with a more versatile version.