Академический Документы
Профессиональный Документы
Культура Документы
Laboratory Manual
CONTENTS
1. Documentation Guidelines
18
27
29
32
52
Documentation Guidelines
Laboratory Reports
All laboratory reports will have a cover page with the students names, the class, the
problem number and the problem title prominently displayed.
All lab reports must include printouts of graphical waveforms showing simulation results
and log files of the simulations done. Resolve any errors or warnings before submitting a
lab report. Submitted log files may not contain warning or error messages. All text,
code and waveforms are to be computer printed without edits. You may copy the file
into a word processor adding page breaks, titles and page numbers but nothing more.
While these computer-generated outputs and all source code must be included in a lab
report, they are supporting documentation, not the body of the lab report. The essential
elements of a lab report are:
A statement of what you are accomplishing, demonstrating, determining,
etc.
Methodology: statement of how you did it. Specifically include a test plan.
Include flow charts and other materials as appropriate.
Analysis of results: what did you demonstrate/prove.
Conclusions.
Any lab report without the above elements will be incomplete and will be graded
accordingly.
Academic Dishonesty
Submitting any report that is not entirely your own work is a form of academic
dishonesty and will not be tolerated. Each and every lab report must include the
following statement, signed and dated by the student. Lab reports without the statement
will be summarily rejected.
I hereby attest that this lab report is entirely my own work. I have not copied either
code or text from anyone, nor have I allowed or will I allow anyone to copy my
work.
Name (printed)
_______________________________
Name (signed)
Documentation
This is a course about hardware development using a hardware description language. The
application may be modeling hardware but the method is coding of language constructs.
As such, documentation of your circuit descriptions will be a key part of the grading.
All modules should be clearly written and well documented.
The purpose of documentation is to identify the code and to explain both the what and
the why of the code. In school, documentation is also where you demonstrate your
understanding of class material. Part of learning the skill of documentation is knowing
what is important and what is trivial. Do not document the trivial. Over the course of the
class, what is new and important in the early problems may become trivial later on.
Each module should have a header that identifies it and its author(s). An example is:
/***************************************************************************
***
***
*** EE 526 L Experiment #1
Student_Name, Spring, 2003 ***
***
***
*** Experiment #1 title
***
***
***
***************************************************************************
*** Filename: Filename.v
Created by Student_Name, Date ***
***
--- revision history, if any, goes here --***
***************************************************************************/
Module headers must give the filename, the author(s) and the experiment number.
You will write and debug modules without documenting each change. But once
submitted, further changes should be noted. There will be such cases: a clock module,
used with one problem, then modified and used with another problem. That second use
may require several changes but only the overall change should be documented.
Normal practice, whether for this course or in professional engineering environments, is
to put each module in a separate file, although it is perfectly legal to combine modules in
one file. Whether separate or combined, each module must have a module header that
describes it.
Module Purpose
After the header, document the purpose of the module if its not obvious. A module that
models hardware should describe what it models and anything special or important about
how the modeling is done. A module that tests another module or modules (called a
testbench) should document what it tests and what its test strategy is.
Test Plan
A test plan is a high-level description or executive summary of the tests performed by
the module. It is not an exhaustive list of all the tests being performed. Every lab report
must include a test plan documenting what tests are to be performed and explaining why
they are adequate for the device under test. For most labs, an exhaustive test strategy is
impractical, so some thought will have to be put into devising an adequate yet nonexhaustive test plan. It is extremely unlikely that a test plan that does not cause every
circuit output to change states at least once will be satisfactory.
An example test strategy for testing an 8-input MUX might be:
Test strategy: Test A-path (all ones, all zeros and alternate bits), B-path, undefined and
hi-z select, example undefined and hi-z on A- and B-path inputs.
An example test strategy for testing an adder might be:
Test strategy: Apply all 0 and 1 cases, with and without carry-in to test carry
propagation (or no-carry propagation); apply alternate 1-0 and 0-1 cases (each cell adds
without carry-out); apply alternate 1-0 and 0-1 cases (each cell adds with carry-out); add
max positive and max negative with and without carry-in to test for arithmetic overflow.
An alternate test strategy for the adder might be:
Test strategy: Generate exhaustive test of all combinations of X- and Y-inputs and
carry-in.
When the purpose of a test is not obvious, add a parenthetical comment explaining what
is being tested (e.g. carry propagation).
Model Documentation
Where different modeling approaches are possible, explain your choice. For example,
there are different ways of assigning values to variables and they have subtle differences
in their operation. Your documentation should indicate your understanding of the
differences and why the chosen construct is the correct choice for this particular model.
Any of the following cases require explanation (and this is not an exhaustive list!):
1. Use of an intra-assignment delay.
2. Use of a non-blocking assignment.
3. Use of a clocking construct (posedge or negedge) with a signal other than a
clock or reset.
4. Use of a wait delay.
5. Use of a procedural continuous assignment with a signal other than a reset or
preset.
6. Use of multiple procedural continuous assignment statements with a single
signal.
7. Handling of exception conditions such as simultaneously active read and write
strobes or arithmetic overflow.
In industry, there is a strong bias for reusing modules. This requires that each module
document any limitations or unusual behavior. This applies in the lab, too. If your model
is incomplete in some fashion, whether by hardware limitation or abbreviated coding you
must identify the limitations that flow from that incompleteness. For example, an adder
module may have no signal to indicate arithmetic overflow. You must document this in
your module.
Modeling Style
Modules have different sections and different functions. Especially for the first few
problems, you should identify each section of each module: port or signal declarations,
netlists, module instantiations, signal display, test stimuli, etc. In all cases, you should
use a blank line or two to separate sections. When modeling sequential logic, its usually
a good idea to model synchronous and asynchronous functions separately.
// Describe the asynchronous behavior
code
// reset is active low
// Describe the synchronous behavior
code
// clock is positive edge triggering
Use indentation to indicate the level or importance of each line of code. Indentation
improves the look of the code, organizes it and because delimiters should pair at the same
level of indentation it aids in troubleshooting.
A TAB indents too far so use three or four spaces for each level of indentation. All code
between the module and endmodule keywords is subordinate to the module and should
be indented one level. Code outside the module (typically `timescale or `define) is at the
same indentation level as the module keyword.
Some constructs have subordinate clauses or subprocesses. These should be indented
below the superior process. For example:
initial
initialization_action;
if (test_clause)
action_if_test_is_true;
Other constructs serve to delimit sections of code. The most common is the beginend
keyword pair. Others include fork join and case endcase. All code within these
delimiters should be indented one level below the delimiter. The delimiters themselves
may also be indented as shown in the following examples:
if (test_clause)
begin
true_action_one;
true_action_two;
end
else
begin
false_action_one;
false_action_two;
end
Lines that are too long to fit comfortably on a page, i.e. longer than about 75 or 80
characters, can be broken anywhere there is whitespace, typically right after a comma.
The rightmost part of the line is indented at its proper level. The remaining part or parts
of the line are indented one more level.
Strings are an exception to the break the line at whitespace rule. Strings cannot
continue on a second line. They must be broken into two separate strings, each on its
own line and (usually) separated by a comma. Strings can, however, be broken anywhere
except between the backslash and following character of so-called escaped characters.
A long string cannot be broken somewhere in the middle and continued
on another line.
But a long string can be broken into two strings, one on one line, a comma,,
and the other on the following line.
Very occasionally (in this class, at least), a statement is both long and deeply indented.
Breaking such a line according to the usual procedure results in many short, choppy lines
that are difficult to read. In such cases, outdent or move up (left) in indentation levels so
that more of the statement can appear on each line. As a rule of thumb, outdent at least
two levels. Of course the outdent is used only for the extremely long statements and
should not be continued with later statements.
module
o
begin
Short_statement_isnt_outdented
Extremely_long_statement_deeply
indented_and_broken
according_to_usual
procedure_resulting_in
many_short_and_choppy
lines
Extremely_long_statement_deeply_indented_then_outdented
So_more_of_the_statement_appears_on_each_line_thus
Making_the_statement_easier_to_read
Another_extremely_long_statement_deeply_indented_then_outdented
so_more_of_the_statement_appears_on_each_line
Short_statement_isnt_outdented
Short_statement_isnt_outdented
Short_statement_isnt_outdented
end
o
endmodule
Commonly the $monitor and $display statements, while not deeply indented, will still
extend far beyond the right margin of the page. These statements can be broken
anywhere there is a comma (except within a string):
$display (----Time---- ----Address---- ----Data ---- Rd Wr ALE M/IO,
s0 s1 NMI TxD RxD);
$monitor ($time, %hAdr %hData %b %b %b %b ,
%b %b %b %b %b, MemAddr, MemDat, Read_Not, Write_Not, ALE, Mem_IO, Status0, Status1,
NMI, TxData, RxData);
The printout generated by a monitor or display statement may also be longer than a
printable line. Such lines can be compacted or indented with the \n and \t constructs,
signifying newline and tab, respectively.
For all submitted printouts, all lines must fit. Any lines exceeding the printable width
(and therefore not available for review) will be penalized. It is the students
responsibility to ensure that the full text of any line is printed.
Verilog allows variable names to be essentially unlimited in length. It is therefore
advisable to assign descriptive variable names wherever possible (clock, select, data_in,
etc.). On the other hand, someone must type these long variable names and every
additional character increases the chance of a typo, so some restraint is necessary. One
exception is loop indices where single letters, typically i, j, k, etc. are common and well
understood.
module mux2(A_Input,
B_Input,
Select,
Enable,
Mux_Out);
//
//
//
//
//
LS mux input
MS mux input
Select signal (see truth table above)
Mux enable, active low
Mux output
10
11
FUNDAMENTALS OF TESTING
To be detected, a fault condition must yield a different output than the fault-free
design for at least one test pattern of the test suite. Every signal line should exhibit both
logic states during the test. (This is a necessary but not a sufficient condition for testing
that signal.) A test suite designed to detect single stuck-at faults will also detect a high
percentage of multiple faults including bridging faults. Not all faults are testable due to
redundancy in the design. (Redundancy means non-minimal logic but may be necessary
for hazard elimination or for fault tolerance). Because it focuses on the individual nodes
and signal paths in a design, stuck-at fault testing is not particularly effective at testing
algorithms and functions. (Remember that the individual logic elements will probably all
function correctly in a circuit with design faults).
TEST STRATEGIES
Exhaustive test: apply all combinations of logic states to the inputs (usually as a
binary counting sequence). Easy to create. Detects all detectable faults. Works only
on combinational logic (but with correct signal segregation and control, can
sometimes be used with sequential logic). Test time doubles for each added input.
High degree of redundancy in the test suite for all but the smallest circuits and
redundancy increases with number of inputs. A divide and conquer strategy can cut
test time by limiting testing to independent blocks of logic.
Heuristic test: apply limited set of hand-generated test vectors. Human beings can
often identify the most important areas to be tested. Is not systematic or algorithmic.
Often the method of choice for functional testing. Fault detection or fault coverage
depends on the skill of the test designer.
12
Logic gates
Outputs
Inputs
Inputs
Outputs
Logic gates
Clock
Reset
Memory
Elements
13
14
Test vectors that find many faults are said to be robust. Test time is valuable
and the less of it used, the better provided, of course, that the necessary faults are
checked. Recall the statement that stuck-at fault testing was not particularly good at
verifying functionality. True, but if functional test vectors are written so that stuck-at
testing can also be done, the vectors are probably quite robust. Students will be
expected to write robust test vectors, i.e. to minimize the number of test vectors while
maximizing the number of faults checked.
Typical questions to ask (although not all questions apply to every problem):
Are different inputs distinguishable by different patterns?
Can reversed bit ordering be detected (especially across module boundaries)?
Can shorts between adjacent bus signals be detected?
Do the asynchronous functions work: does SET make a low output go high and a
RESET make a high output go low? Does ENABLE work? Does a tri-state
ENABLE work?
Do the synchronous functions work: do outputs change only on the right clock edge?
Do the asynchronous functions override the synchronous functions?
Is the state table or transition table verified with the given test suite? Have unused
states been checked?
Is the control table or are the control functions verified with the given test suite?
Have data inputs been toggled for every combination of control states? Have unused
combinations or states been checked?
Are anomalous, illegal or exception conditions tested and does the circuit conform to
specification or at least do something reasonable. Does the model generate a warning
message for illegal inputs?
Have all inputs and outputs and as many internal signal lines as possible been
switched between logic states?
Have undefined (bx) and high impedance (bz) states been applied to critical inputs?
Have the input and output extremes been tested (largest, smallest, positive, negative,
leftmost, rightmost, etc.)
Has the test suite been documented to indicate what is tested, assumptions made, and
tests omitted (if any)?
simulate correctly but would either fail to produce any hardware at all or produce
defective hardware when synthesized. These stylistic errors are easy to avoid. While the
list below is not exhaustive in that there is an infinite variety of ways to produced
defective designs, by following these guidelines many common errors can be avoided.
1. Always have an else clause for every if.
2. Have a default clause for every case statement.
3. If one signal in a sensitivity list is edge sensitive, all must be.
4. Avoid all use of combinational feedback. Sequential feedback is fine.
5. Avoid all use of continuous assignments for anything other than bidirectional
port interfaces.
6. Do not put explicit time delays into circuit descriptions. Their use is limited to
non-synthesizable test fixtures.
7. Clock and reset signals are always primary inputs.
8. While there are sometimes valid reasons for violating synchronous design
guidelines, none of them apply to the labs in this manual. Synchronous design is
mandatory for all designs in this course.
9. Never split assignments to any one variable between always blocks.
10. Use only one assignment operator (blocking or non-blocking) for any
operand.
Some of the above rules are likely to seem esoteric and incomprehensible at the start
of the semester. Refer back to this list as the semester progresses and you learn
more about behavioral hardware description.
16
Experiment # 1
Familiarization with Linux and the Synopsys VCS Simulator
Note that there frequently is more than one way to accomplish a task in Linux. As you
develop proficiency with this operating system, you may find procedures that will work
as well as or better than the ones specified here.
Log into any of the workstations in the laboratory by entering your account number and
user password. Once you logged into the system, a graphical user interface will start. To
access lab tools you need to open a terminal window. The Terminal window accepts
Linux OS commands, which are summarized in Appendix A. Open a terminal window by
right mouse clicking on the empty desktop space to bring up the Workspace menu and
selecting Open Terminal with a left click. This will give you a terminal window as shown
below. The window may be resized with the mouse.
17
18
19
20
To populate this environment, left mouse click on File and select Open Database. From
the Open Database window, select vcdplus.vpd, as shown in Figure 6. This will cause the
DVE window to show your top level design (the test fixture) in the Hierarchy window
and the unit under tests primary input and output signals to be displayed in the Variable
window, as shown in Figure 7.
Select all the signals with the mouse, then right click and select Add to WaveNew
Wave View. This will cause the view shown in Figure 8 to appear.
21
22
23
24
25
n1
SD
NAND2
NAND4
n2
NAND1
CP
J
a1
n3
AND1
nr
NOR1
NAND3
NAND5
a2
AND2
RD
JK_ff.vsd
1. Using primitive gates, write a Verilog module for the J K flip-flop shown above.
In your module,
a. Use the following module header:
module flop(J, Kb, SDb, CP, RDb, Q, Qb);
o
o
o
endmodule
26
Delay
time_delay_1
time_delay_2
time_delay_3
time_delay_4
Time Steps
2
4
6
15
SD
0
1
0
1
1
1
CP
x
x
x
0
1
0
K
x
x
x
0
1
1
x
x
x
RD
1
0
0
1
1
1
Q
1
0
1-?
0
1
q
q
q
Q
0
1
1-?
1
0
q
q
Mode
Async Set
Async Reset
Indeterminate
Load 0 (reset)
Load 1 (set)
Hold (ncng)
Toggle
Hold (ncng)
q
(x = dont care, = positive edge, = not a positive edge)
The inputs must be stable before the clock edge. You can cause rising edges on the
clock line by first setting it to 0 and then to 1. You should experiment with a
symmetric clock (50% duty cycle) and with a clock that uses only a short positive
pulse.
Be sure to allow sufficient time between input changes for the effects to propagate
through the circuit. This is a sequential circuit and must be tested accordingly. How
fast is too fast for your device? Answer this for both 50% and short cycle clocks.
27
Using primitive gates, write a Verilog module for the SR Latch shown in Figure
1. Use a header similar to the one shown below, but use a suitable timescale for
the delays indicated in point 3.
`timescale 1ns/1ns
module SR_Latch2(Q, Qnot, s0, s1, r0, r1);
output Q, Qnot;
input s0, s1, r0, r1;
o
o
o
endmodule
Save your module in a Verilog file with the same name as the module.
2.
Using the SR_Latch2 module and primitive gates, write a Verilog module for the
positive edge triggered flip-flop shown in Figure 2. Use the following module
header:
module dff(q, qbar, clock, data, clear);
output q, qbar;
input clock, data, clear;
o
o
o
endmodule
Save your module in a suitably-named .v file.
3.
28
ways to make this work. Creating different designs, one for each delay
characteristic, is not an acceptable solution.
4
Write a Verilog model of the 8-bit register with the organization shown in
Figure 3. The register has the logic symbol shown in Figure 4. From its symbol,
the functions of the registers reset (rst) and enable (ena) can be inferred. Use the
following module header:
module register(r, clock, data, ena, rst);
output [7:0] r;
input [7:0] data;
input clock, ena, rst;
o
o
o
endmodule
Incorporate a clock generator with a suitable period for your design in your test
fixture.
To reduce typographical errors, put your invocation of the compiler into a force
file. This is a text file that contains all the commands and arguments you would
otherwise have to type in on the command line with each invocation of the
compiler.
For example, if you have design files FileA.sv and FileB.sv and test fixture file
tb_TOP.sv, your force file would consist of
vcs debug sverilog FileA.sv FileB.sv tb_TOP.sv
Save the force file in a suitable file time with a .f extension.
By default, Linux files are not executable. Make your force file executable by
typing from the command line
chmod +x <filename>.f
29
s0
SR Latch
Figure 1
s1
Qnot
r1
r0
sbar
cbar
clr
clear
clkbar
clk
qbar
clock
r
dbar
data
d
rbar
data[0]
r[0]
dff
data[7]
MUX
MUX
r[7]
dff
ena
clk
rst
ena
ena
clk
clk
rst
rst
data[7:0]
register
r[7:0]
30
data[4:0]
load
enable
clock
Counter
reset
cnt[4:0]
31
32
Scalable
Multiplexer
a[size-1:0]
out[size-1:0]
b[size-1:0]
sel
Exp5_aa.vsd
33
largest multiplexer with as many bits as it needs for its a and b inputs. Use as many of the
least significant bits of the a and b buses as needed to drive the smaller instances. The
test vectors for the largest multiplexer should be sufficient to also test the smaller
multiplexers.
NOTE: when testing sel = 1bx, you must apply a = b and a b cases and at least one
case where a and b share some common bits and some opposite bits.
Does your model function the same as the gate-level model simulated in Lab 1? Should
it?
34
35
7. To prove your exhaustive testbench will find an error, use a force assignment to
override the behavioral adders sum sometime after of the test vectors have been
applied. Use the `ifdef and `endif compiler directives to include or exclude the code
that forces an error.
In your report, include log printouts from both the error-free and forced error cases. Use
$monitoroff and $monitoron commands to show only the first dozen or so test vectors
(and results) and the last dozen or so for the error free case. For the forced error case, use
them to show the first dozen or so test vectors and about a dozen test vectors before and
including the forced error.
For the error-free case, include SimVision printouts showing the start and end of the test
in sufficient detail to verify the applied signals and how they change. You may, if you
wish, submit one or more overview printouts as well.
For the forced error case, include SimVision printouts of the end of the test in sufficient
detail to see when and how the forced error is applied and how the modules react.
To make your output easy to analyze, use decimal numbers and show input values, output
values and expected output values.
36
a5
b5
a4
b4
FA
FA
MUX
FA
b3
FA
MUX
a3
b2
FA
FA
MUX
a2
MUX
a1
FA
FA
MUX
MUX
s3
s2
b1
a0
b0
1
c2
FA
FA
s1
s0
c4
c6
s5
s4
MUX
sel
0
1
out
x
y
sel
carry
out
FA =
Full Adder
out
sum
carry
in
c0
A register file operates similarly to random access memory but is made from flopflops
rather than DRAM or SRAM cells. A register file would consume far more power and take
far more area than a true memory of the same capacity. However, register files have the
advantages of operating fast, faster even than SRAM, and they can easily be coded in any
arbitrary size (width and depth) in Verilog. In this lab, you will create a register file that
will be used as a random access memory.
Use parameters for both width and depth in your model. Where specific sizes are given in
the description below, make those the default values for your parameters.
1. Create a Verilog model of a register file with the following specifications:
a.
b.
c.
d.
e.
f.
g.
h.
i.
40
Assume the address bus is stable before or at the assertion of oe or ws and remains stable
for at least the access time of the memory. Assume cs will never be changed during a read
or write cycle.
2. Create a Verilog testbench for your memory. It must do the following:
a. write to and read from every memory location.
b. demonstrate both an individual and a block read.
c. demonstrate the specified timings for read and write.
d. test both enabled and disabled memory states.
e. demonstrate that the data bus is in the high impedance state sometime during
the test (typically when oe = ws = cs = low).
f. demonstrate there are 32 locations in the memory (hint: write then read back
and verify a unique value for each address).
g. demonstrate there are no shorts or stuck-at conditions on the data lines. This is
something that is typically done in factory test, not verification, but you can still
write vectors to perform this test.
Note: some of these requirements can be combined in a single test.
41
C9 8F A0 9B
86 95 FD B1
65 11 03 4C
42
43
44
Addr[5:0]
B_EN
Opcode[3:0]
PDR_EN
PORT_EN
Phase[2:0]
ALUFlags
Sequence
Controller
IFlag
PORT_RD
PC_EN
PC_LOAD
MAR_EN
ALU_EN
ADDR_SEL
MEM_OE
MEM_CS
45
The instruction fetched from memory determines which control lines will be asserted
during later cycles. For example, if the operation is a Store, neither Load A nor Load B
will be asserted at any time during the eight cycles, but one of them will be asserted in
cycle three if the operation is a load targeting one of those registers.
46
During the Load Register cycle (Cycle 3), immediate data are latched into one of the
registers according to signals sent from the Instruction Register. Immediate data means that
the data are contained in the instruction, as opposed to being stored in a different memory
location. When data must be fetched from a different memory location, the registers will be
loaded in Cycle 6 rather than Cycle 3. Immediate data are signaled by setting the I Flag.
There are five registers that may be enabled during the Load Register cycle: A and B of the
ALU, the Port Direction Register, the Port Data Register and the Memory Address
Register. The sequencer needs one output for each so that it can enable the appropriate one
during this cycle. The sequencer also needs to control the memory address bus selector,
the memory output enable and the memory chip select.
If the opcode is an ALU operation, the ALU will be enabled in Cycle 4 (EXECUTE cycle).
Cycle 5 is used for setting up memory access in Load and Store operations. In both cases,
the memory address bus must be switched to use the address from the Memory Address
Register rather than the Program Counter.
In Cycle 6, ALU output data or port IO data are written to memory if the operation is a
store. In the case of Load, data from the memory are latched into the selected target
register in this cycle.
In Cycle 7, the Program Counter is updated. The PC is external to the Sequencer but needs
to be enabled by the Sequencer. It can either be incremented or loaded with a new value. It
has two control signals, both set by the Sequencer: Enable and Load. Enable will always be
activated in Cycle 7. Load will only be activated if a Branch or Jump is to be performed.
This is determined by decoding both the opcode and the four ALU flags. If the opcode is
Jump, Load will be activated. If it is BZ, it will be activated only if the Z flag is set. If it is
BN, it will be activated only if the N flag is set, etc.
Each instruction will have the following format:
Bits
31 : 28
27
26 : 21
20 : 8
7:0
Table 1 is for reference only in this lab. For this lab, the various fields are already broken
out as inputs to the sequencer as needed. The data field is not used in this lab.
Note that although there are Load and Store opcodes as well as Load and Store phase
states, they are not the same thing. There is no direct correlation between them. It would be
47
illegal to use one as a localparam and one as a typedef in the same scope anywhere in the
design.
Clock
Reset
Ph1
Ph2
Ph3
Lab 9 Figure 3: Phase Generator Signals. Use Enumerated Types for the eight states.
Memory mapping
The RISC processor for which this is the controller will be memory mapped as shown in
Table 2. This means that in addition to the 32-deep combined program and data memory,
some machine registers and the I/O port will also be enabled for reading and writing when
addressed. Enabling memory mapped devices requires reading the address bus along with
the opcode. When addressing a memory-mapped register, the main memory should be
disabled.
Lab 9 Table 2: Memory Map
Decimal Address
Device
0-31
Memory
32
ALU A Register
33
ALU B Register
34
Port Direction Register
35
I/O Port
36
Memory Address Register
Any address not covered by the above table is not implemented. Reading from an
unimplemented address will produce unpredictable results. Writing to an unimplemented
address will have no effect.
Note that I/O Port read and write share the same address. Setting the enables is
distinguished by the opcode: when LOAD, data are written to the Port Data Register.
When STORE, the I/O Port drives data onto the bidirectional memory bus. To avoid
contention, the memory output must be disabled when the port is driving, though the
memory chip select must remain active so that new data may be written to the memory.
The instruction set for the CPU is shown in Table 3 below. Any opcode not covered shall
be illegal. You do not need to do anything in hardware to detect illegal input conditions.
48
OPCODE
4'b0000
4b0001
4b0010
4b0011
4b0100
4b0101
4b0110
4b0111
4b1000
4b1001
4b1010
4b1011
4b1100
49
enable
clk
phase
generator
Phase
[2:0]
reset
Exp9_ea.vsd
50
simulation either completed correctly or failed. Use force and release to inject errors and
demonstrate that your test fixture is capable of detecting faulty operation.
Use name declaration (dot naming) to connect signals between the testbench and the
modules under test. List signals in reverse order from their original order in the module
port list. Previously we have used positional declarations.
Both your controller module and your testbench should be well documented. In particular
since the testbench is automated, be sure you document your test strategy.
51
These modules can be put together to form the following RISC-Y CPU system. However,
instead of instantiating the register from Lab 3, you will model several registers of
appropriate sizes behaviorally.
The RISC-Y processor is typical of modern Reduced Instruction Set Computer
architectures such as the ARM family of processors used in virtually all smart phones in
that it has a small, regular instruction set and a load-store architecture. Though it is far
simpler and more stripped down than any current-production machine, it is a complete
microprocessor and could be programmed to accomplish any general purpose computing
task.
Each RISC-Y instruction will use the following format:
52
There are only two possible objects that may be stored: the ALU output and the port. When
the opcode is STORE, the Address field is checked to see if it contains 35, which is the
address of the port. If there is a match, port data are stored in the address indicated by the
least significant bits of the Data field. For any other address, the ALU contents are stored.
ALU opcodes (ADD, SUB, AND, OR, XOR and NOT) do not need to reference any fields
other than the opcode. They always use the A and/or B registers for operands and the result
always goes to the ALU results register.
The remaining opcodes are all branches. For these operations, the branch address will be
contained in the lowest five address bits. These bits are loaded into the Program Counter.
The major component groups of the RISC-Y CPU are shown in Figures 2 through 4 below.
53
In addition to the blocks shown in these diagrams, the sequencer and its associated phase
generator from Experiment 9 need to be instantiated and connected. Use the enumerated
type created in Experiment 9. Do not convert it to plain binary.
54
The design is to be totally synchronous. The only clock is the master clock. No
derived signals may ever be used as a clock.
While it would be logically correct to use the primitive operator register design
from lab 3, that function should be re-designed using behavioral code. The
behavioral code should not have any delays specified.
A Program Counter points to the next location in memory from which the CPU will
fetch instructions or data. The PC is the counter from Lab 4. It may be loaded with
branch addresses or incremented to go on to the next address in sequence.
The ALU only receives operands from the A and B registers, which are eight bits
apiece.
There is one eight-bit input-output port. When it is an output, data can be written to
it by executing a LOAD operation with the ports address (35) in the address field. It
is read by performing a STORE operation with the store address in the data field
and the port address of 35 in the address field.
55
When an eight bit quantity is loaded or stored, the active bits are always the eight
least significant of the referenced memory location.
The port direction is set by writing to the Port Direction Register, address 34. This
is a one-bit register. To simplify the design, all bits operate together as either input
or output.
Data for the one-bit Data Direction Register will take its data from the least
significant bit of the referenced memory location. It can only be changed via a
LOAD operation. There is no provision for reading this register.
The tristate data bus must never be allowed to float. Exactly one driver must always
be active. This means that some modification to the logic controlling memory read
and write will be necessary to prevent a floating bus.
56
All steps should be well documented and the results well presented! All instructions
and conditions should be tested.
Multiple test program files are likely to prove advantageous rather than trying to
demonstrate correct functioning of all instructions in one file.
Remember to zoom in so that submitted waveforms are readable. You may, if you wish,
also submit one or more zoomed out overview plots.
57
Appendix A
UNIX Command Reference Guide
58
clear
GENERAL CONCEPTS
C-key
While holding down the control key
(also marked Ctrl), press the key after the dash.
C-c means hold the control key and type c.
options Generally, UNIX command options are
specified with a character or character string that
begins with a - (dash). In the example man -k
mail, -k is an option for the man command.
Many times, the order or placement of options is
significant.
CONTROL CHARACTERS
RET
Carriage Return. It sends a completed
command to the system.
C-c
Aborts (interrupts) the current
command or program.
C-z
Stops or suspends the current process.
C-s
Halts the scrolling of output to the
terminal.
C-q
Continues scrolling.
C-o
Stops (flushes) output from being seen
on the terminal.
C-r
Redisplays the command line.
C-u
Erases the command line.
C-w
Erases the last word on the command
line.
DEL
(Delete key) Deletes a single character from
the end of the command line.
BREAK (Break key) Three BREAKs can disconnect
your terminal from the system in an emergency.
SESSION CONTROL & PRIMARY COMMANDS
passwd Invokes program to change login password. You
are prompted for old and new passwords.
logout Terminates the login session.
exit
Exits the current shell.
ps
(with no options) shows your process.
setenv Changes variables associated with your
59
>>
tee
script
MAIL
mail
COMPILATION/DEBUGGING COMMANDS
cc
Invokes the C compiler.
f77
Invokes the FORTRAN-77 compiler
pc
Invokes the Pascal compiler
dhx
Invokes the symbolic debugger. You must first
compile your program with the debug option
enabled.
?
h
INFORMATION COMMANDS
date
Displays the current date and time.
finger
Displays all users currently on the system.
chfn
Changes the information shown when someone
issues the finger command.
cal
Displays a calendar of the current month. Use
cal mo yr for a specific month or cal yr for a full
year. (yr may be 19999 so all digits must be
given).
t
n
e
d
u
COMMUNICATION COMMANDS
mesg
Allows you to receive or block messages to your
terminal. Options are y and n.
write
Puts you in direct communication with another
user. write user will allow you to communicate
with user. Everything you type will appear on
users terminal. To stop communication, press C-d
on a new line.
s
r
m
q
60
Appendix B
vi Editor Command Reference Guide
61
[[
]]
EXITING vi
:w
Writes the editing buffer to disk. If you specify
a following filename, writes the buffer to a file with
that name.
:q
Exits vi without writing to disk.
:wq
Writes the file to disk and then quits.
:x
Writes the buffer to disk only if changes have
been made since the last write then quits.
ZZ
Same as :x.
Q
Puts you in ex command mode. Use the ex
command vi to get back into visual mode.
x
`x
+
-
CURSOR MOVEMENTS
b
Moves back one word (bounded by punctuation
or whitespace).
B
M oves back one word (bounded by whitespace).
e
Moves to the end of current or next word.
E
Moves to the end word until whitespace character.
f
Moves to next occurrence on the current line of
the character you type next.
Fx
Moves to previous occurrence on the current line
of the character you type next.
(n)G
Moves to last line of file or line number n.
h
Move back one space.
j
Moves down one line.
k
Moves up one line.
l
Moves forward one space.
(n)L
Moves to bottom of screen or n lines from bottom.
M
Moves to beginning of middle line of screen.
tx
Moves to the space before the next occurrence of
character x on the current line.
Tx
Same as t but scans backwards on current line.
w
Moves to beginning of next word (bounded by
punctuation or whitespace).
W
Moves to beginning of next word (bounded by
whitespace).
S
Moves to last character of current line.
%
Moves to ), ], or } matching next occurrence of (, [
or {, respectively.
^
Moves to first nonwhitespace character on current
line.
(
Moves to beginning of current or previous
sentence.
)
Moves to beginning of next sentence.
&
Repeats last substitution (executed with last line
command s) on current line.
{
Moves to beginning of current or previous
paragraph where a paragraph is marked with one of
the nroff paragraph macros. Type :set all to see
what these are.
EDITING COMMANDS
a
Appends text after the cursor.
A
Appends text at end of current line.
cc
Changes one line to the next text typed.
cx
Changes from cursor to place delimited by cursor
movement x.
C
Changes current line from cursor to end.
dd
Deletes one line.
dx
Deletes from cursor to place delimited by cursor
movement x.
D
Deletes from cursor to end of current line.
i
Inserts text before the cursor.
I
Inserts text at beginning of current line.
J
Joins current line and next line.
mx
Marks current line (and current cursor position)
with letter x.
o
Opens new line below the current line.
O
Opens new line above the current line.
62
p
np
xp
cursor.
P
nP
xP
r
next
R
s
S
u
U
x
X
yy
Y
xyy
&
~
(n)>
(n)<
with letter x.
vi ENVIRONMENT OPTIONS
all
Displays a list of all the currently set option values.
autoindent (ai)
Used for writing structured programs
where indentation is important for determining
levels of embedded commands. When set, vi
indents each line you type an appropriate amount
dependent on the indentation of the previous line.
autoprint (ap)
Displays the current line after each
copy, move, or substitution (s) command.
ignorecase
When set, the case of letters in regular
expressions (in search patterns) is ignored except in
ranges within square brackets.
magic
When nomagic is set, all magic characters (used in
regular expressions) except ^ (beginning of line)
and $ (end of line) lose their magic properties. By
default, magic is set but even when nomagic is set,
you can turn on the magic of individual characters
by preceding them with \ (backslash).
mesg
By default, nomesg is set. When set, mesg allows
other users to write to your terminal with the write
command which can temporarily scramble your
screen.
number When set, the number of each line is displayed at
the left of the screen.
report
report=5 is set by default. This option determines
the threshold at which the number of lines deleted,
copied, moved or changed is reported.
showmatch
When this optionis set, each time a ) or }
is typed in insert mode, the cursor jumps quickly
back to show the matching ( or {.
showmode
Causes the message INPUT MODE to
be displayed in the lower right corner of the screen
when you are in insert mode.
wrapmargin
By default, wrapmargin=0 is set. When
a different numerical value is set, causes a
RETURN to be inserted that number of characters
from the right edge of the screen in insert mode.
SEARCHING
f
Finds next occurrence on the current line of the
character typed next.
F
Finds previous occurrence on the current line of the
character typed next.
tx
Moves to the space before the next occurrence of
character x on the current line.
Tx
Same as t but scans backwards on the current line.
,
(comma). Repeats last search with f, F, t or T but
reverses direction.
Searches for next occurrence of expr (any regular
/expr
expression in the file.
63
wrapscan
64