Lab7 - Fetch Unit

We are ready to build the actual simulator machine. But to do this, we need to “refactor” the current project you have in the attiny85sim project folder.

The first thing you need to do is set up the project directories and the Makefile needed for the project.

The structure you need looks like this:

attiny85sim/
├── Makefile
├── include
│   ├── Component.h
│   ├── Pin.h
│   ├── Register.h
│   ├── Wire.h
│   └── catch.hpp
├── lib
│   ├── Component.cpp
│   ├── Pin.cpp
│   ├── Register.cpp
│   └── Wire.cpp
├── src
│   └── main.cpp
├── tests
│   ├── test_main.cpp
│   └── test_sanity.cpp
└── verilog
    └── fetch.v

You do not really need the verilog folder, unless you want to play with Verilog.

Here is the Makefile I am using to build the example code:

Makefile
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# Makefile for attiny85sim

include debug.mak
include project-version.mak
include help.mak

TARGET	:= attiny85sim
TSTAPP	:= testapp

# C++ source files
SSRCS	:=	$(wildcard src/*.cpp)
LSRCS	:=	$(wildcard lib/*.cpp)
TSRCS	:=	$(wildcard tests/*.cpp)

# C++ object files
SOBJS	:= $(SSRCS:.cpp=.o)
LOBJS	:= $(LSRCS:.cpp=.o)
TOBJS	:= $(TSRCS:.cpp=.o)

CFLAGS	:=	-Iinclude -std=c++11

$(TARGET):	$(SOBJS) $(LOBJS)
	$(CXX) $(LFLAGS) -o $@ $^

%.o:	%.cpp
	$(CXX) -c $(CFLAGS) -o $@ $<

run:	$(TARGET)
	./$(TARGET)

$(TSTAPP):   $(TOBJS) $(LOBJS)
	$(CXX) $(LFLAGS) -o $@ $^

test:	$(TSTAPP)
	./$(TSTAPP)

clean:
	$(RM) $(TARGET) $(SOBJS) $(LOBJS) $(TOBJS)

# version management targets
.PHONY: version
version: ## show current project version
	@if ! ([ -f .version ]); then \
		echo "v0.0.0" > .version; \
	fi
	cat .version

.PHONY:	tag
tag: ## tag this version
	@echo $(VERSION)
	git tag -a $(VERSION) -m "Auto tag $(VERSION)"

.PHONY: bump-build
bump-build:	## bump version build number
	./scripts/inc_version.sh build;

.PHONY: bump-feature
bump-feature: ## bump version feature number
	./scripts/inc_version.sh minor

.PHONY: bump-release
bump-release: ## bump version release number
	./scripts/inc_version.sh major


Building the Program Counter

We will build the fetch unit is stages. This first step is designed to get you building a new class that uses inheritance. Follow along in the lecture notes and make the changes to your project needed to get the Program Counter set up. In this example code, you are building a fake instruction memory module.

Nake sure your code produces the output shown in the lecture.

Testing your code

The sample code provided proves that the unit basically functions, but is not a good test. As part of this lab, you should add a test in the tests directory that exercises just the Program Counter Register.

To do this, you need to build a register with the correct name, and add input and output pins to it. Then ypu need to run the tick routine to make sure you see the output you expect. The constructor for apin initialized it to a value of 42. If you tick the PC register using the code give, you should get a 42 3 on the output dside. You also habve the ability to reset the register, which puta a zero on the input side. You should then see a one on the output side after another tick.

If you need additional methods in this class to read individual ins, make those changed in the header and implementation. DO not get caught up in the access levels now, just make things public to get them running.

Here is a start on the test code you need:

test_program_counter.cpp
1
2
3
4
5
6
7
#include "catch.hpp"
#include "Register.h"

TEST_CASE( "PC register", "fetch" ){
    Register pc("PC");
    REQUIRE(true);
}

Note

Tag this version as v0.12.0

We will build the Instruction memory in the next part of this assignment. Before we do that, we need to find a way to load code into the memory module.

This lab will end when we have the complete fetch unit running, and have test code to check everything.