EE 361 Fall 02: Homework 6

Due: 10/14/02 (monday)

There are two problems (A and B) for this homework.  Turn in Problem A on paper, and email Problem B -- see below on exactly how to email problem B.

Problem A (2 pt). Design a verilog module for a 2-bit counter circuit. The circuit has output Q which is also the two-bit state of the counter. The output is a 2-bit value Q = (Q[1],Q[0]).  The circuit has inputs:

Turn in your program on paper. However, you should verify that it works using Veriwell, or other simulator.

Note: After designing the counter module, you need some way to test and demonstrate it. Thus, you need a test bench. You may realize a test bench in Verilog by defining another module. The module would look something like this (there may be bugs, so be careful):

module testbench;
reg [1:0] testS, testD;
reg clock;
wire [1:0] q;

// Here we place a counter circuit into our testbench.

Counter testcounter(testD,q,testS,clock);

// We now place our inputs to the circuit to drive it

// The following is the clock signal with period of 2 time units.
initial clock = 0; // initializes clock to 0
always #1 clock = ~clock; // inverts clock every 1 time unit.

// Here we drive D and S
initial begin
D = 2;
S = 3;
#4
S = 1;
#10
S = 2;
#10
S = 0;
#6
end

// Here you can use "display" and "monitor" to output (probe) the
// values of the circuit, to see if it works. I'll leave this to you
// folks to figure out. It's not hard after you see the Verilog
// example in the Bucknell handbook.
.
.
endmodule

module Counter(D,Q,S,CLK);
.
.
.

Problem B. (2 pts) Consider the following simple C program hw6.c:

main()
{ printf("Hello world\n");}

After compiling (using mcc) you get the following assembly language code

	.file	1 "hw12.c"

# GNU C 2.5.7 [AL 1.1, MM 40] BSD Mips compiled by CC

# Cc1 defaults:

# Cc1 arguments (-G value = 8, Cpu = default, ISA = 1):
# -quiet -dumpbase -fno-delayed-branch

gcc2_compiled.:
__gnu_compiled_c:
.rdata
.align 2
$LC0:
.ascii "Hello world!\n\000"
.text
.align 2
.globl main

.loc 1 2
.ent main
main:
.frame $fp,24,$31 # vars= 0, regs= 2/0, args= 16, extra= 0
.mask 0xc0000000,-4
.fmask 0x00000000,0
subu $sp,$sp,24
sw $31,20($sp)
sw $fp,16($sp)
move $fp,$sp
la $4,$LC0
jal printf
$L1:
move $sp,$fp # sp not trusted here
lw $31,20($sp)
lw $fp,16($sp)
addu $sp,$sp,24
j $31
.end main

Before getting to the assignment, let's take a little time to figure out what's going on with the code.

  1. The assembly language program is composed of instructions, labels, and assembler directives. Assembler directives start with periods (e.g., .ascii, .align, .globl. These assembler directives are instructions for the assembler and loader. They are not real instructions for the MIPS processor. You can find a description of assembler directives in Appendix A (pages A-51 to A-53). Here are some of the important assembler directives for the program:

  2. There are several pseudo instructions: la and move. You can also find these in Appendix A.10. Recall that "move" can be implemented using "add".
  3. There are labels that are automatically generated by the compiler: $LCO and $L1.

You can click here to down load this compiled program. This program will not run using xspim because there is no "printf" subroutine. Modify the program so that it runs on xspim:

  1. Change the line .ascii "Hello world!\n\000" to .asciiz "Hello world!\n". Now the ascii string is terminated by a null character (zero).
  2. Add a subroutine "printf" (add it after the line .end main ). The subroutine should have only one parameter passed to it through a register (which register?). It will print the character string pointed to by the register and terminated by the null character. To print characters, use the memory mapped io feature of xspim which is described in Section A.8, pages A-36 to A.38. To print characters you need to use the Transmitter Control Register at 0xffff0008, and the Transmitter Data Register at 0xffff000c. Note that these registers are similar to ones we've had in a previous homework. However, these registers are assumed to be 32 bits (even though at most 8 of those bits are ever used).
  3. When invoking xspim type xspim -mapped_io. This will load the memory mapped io feature of xspim.

To turn in your program

Here are some things to be aware of:

  1. Ignore the reference to "exceptions" (or interrupts) in Section A.8. The default is to turn off the exceptions which is what we want anyway.
  2. You may find that your program prints out "Hello world!" but not the "new line" character (i.e., "\n"). What may be happening is that your program stops the xspim simulator before the last character can be printed. To print the last character, have the subroutine "printf" check for the terminal to be "ready" before jumping to the return address. Having the terminal "ready" means that the last character has been printed.