The document provides instructions for a coursework assignment on analyzing loss control policies of an S&P 500 company. Students are asked to select a company and analyze its policies focusing on environmental loss prevention, catastrophic loss prevention, or employee-related risk management. The analysis should address the likelihood and potential impacts of losses, as well as the company's loss control activities. Requirements include an 8-12 page paper with discussion of the topic areas, works cited, and any attachments. The paper is due by the deadline for extra credit activities in the course.
Introduction to ArtificiaI Intelligence in Higher Education
Analyze Loss Control Policies of S&P 500 Company
1. Fall 2016 Insurance Case Study – Finance 360
Loss Control
Loss control activities of a business focus on finding and
implementing solutions to reduce the probability of loss (loss
prevention) and/or reduce the actual amount of loss (loss
reduction), and therefore reduce the total cost of risk to
maximize firm profitability.
Loss control techniques have been widely used in environmental
loss prevention, catastrophic loss prevention, and employee-
related risk management. Many firms face loss exposures
caused by using, storing, and transporting hazardous materials,
caustic substances, gasses, acids, etc., and may have unique
issues posed by deployment of “greener” vehicle fleets using
CNG, LNG, and bio-fuel solutions. Catastrophic risks, such as
earthquakes, tornado, hurricanes or big fire, also pose
significant threat to the property safety and business
continuation for firms. Employee behavior-related risks and
product safety are also important concern of corporate risk
management.
Lack of effective loss control (such as inadequate systems,
inadequate standards, and inadequate compliance with safety
standards) may cause significant damage to a firm, such as
injury costs, property damage, liability damage, bad press,
lower sales, loss of employee morale, so on and so forth, as
British Petroleum (BP) or Toyota had suffered in the past.
In this project, select an S&P 500 company and analyze its loss
control policies focusing on either environmental loss
prevention, or catastrophic loss prevention, or employee-related
risk management.
2. Your analysis should address the following questions in the
least:
· How likely the firm is subject to catastrophic losses?
· Has the business suffered losses of the kind in the past?
· What losses could be caused to the firm if a catastrophic event
occurs?
A. Direct Property Loss
B. Indirect (or consequential) Property Loss
C. Liability Loss
D. Personnel Loss
E. Crime
F. Other Loss Exposures
· What loss control activities has the firm implemented to
reduce the loss?
· E.g. For Property loss control, comment on Facility design and
construction, Automatic Sprinkler Protection, Preventative
maintenance, Equipment and Process controls and safeguards,
Human Element programs, Pre-incident planning and Business
continuity planning
· Proactive Safety procedures vs. Reactive Safety & Recovery
policies
Requirements
1. Paper length: 8 page minimum, 12 page maximum; 12 point
font—double-spaced
2. Paper sections
A. Title Page, including: (1) paper title, (2) course number and
name, (3) instructor, (4) your name, and (5) date submitted
B. Executive Summary: This is a 1-2 paragraph overall
summary of your paper.
C. Discussion and analysis: Cover all the individual topic areas
set out above, each of which should be labeled with an
appropriate subject heading.
D. Works Cited: List all secondary sources consulted in
3. preparing this paper.
E. Attachments (if any). You may append any relevant
attachment to the paper, and you should refer to these
attachments in the body of your paper.
3. Due date: Turn in the paper with your completed Extra Credit
Activities Summary document by the due date for EC in this
course—noted in the Course Syllabus and in the online
classroom.
H7068 DIGITAL SYSTEMS AND MICROPROCESSOR
DESIGN: COURSEWORK 2019
Remarks:
VHDL. Coursework
handed in using another language will be
marked as zero.
coursework. Typeset code within your
coursework report using a monospace font (e.g. courier new).
Use a proper screen capture tool to include
a high resolution screenshot in your coursework.
a) Consider the register bank of the educational processor (file
cpuregbank.vhd of labcpu):
4. The objective is to create a testbench for this circuit, and
simulate the a few operations
including storing data in it as well as retrieving data from it.
In order to do this, use the file cpuregbank.vhd which is in
labcpu zipfile. The file dffre.vhd is
also required as it is used internally by the register bank.
H7068 DIGITAL SYSTEMS AND MICROPROCESSOR
DESIGN: COURSEWORK 2019
The ports of cpuregbank are:
clk : in STD_LOGIC; -- Clock
rst : in STD_LOGIC; -- Reset signal (active high)
d : in STD_LOGIC_VECTOR(7 downto 0) -- Data to write to a
register
-- (when rwren is enabled)
rwren : in STD_LOGIC -- Set to 1 to write d into register rwr
rwr : in STD_LOGIC_VECTOR(1 downto 0) -- Selects which
register to write to.
-- The register encoding is identical
-- to that used in the assembler
-- instruction encoding.
rrd1 : out STD_LOGIC_VECTOR(1 downto 0) -- Select which
register is
-- mapped to q1
rrd2 : out STD_LOGIC_VECTOR(1 downto 0) -- Select which
register is
5. -- mapped to q2
q1 : out STD_LOGIC_VECTOR(7 downto 0) -- Content of
register selected by rrd1
q2 : out STD_LOGIC_VECTOR(7 downto 0) -- Content of
register selected by rrd2
dbg_qa : in STD_LOGIC_VECTOR(7 downto 0) -- This is a
debug signal which has
-- the content of register RA. It is
-- used in the lab to display the
-- register content on the 7-segment
-- display. (A production processor
-- would not have this signal)
dbg_qb : in STD_LOGIC_VECTOR(7 downto 0) -- Same as
dbg_qa but for RB
dbg_qc : in STD_LOGIC_VECTOR(7 downto 0) -- Same as
dbg_qa but for RC
dbg_qd : in STD_LOGIC_VECTOR(7 downto 0) -- Same as
dbg_qa but for RD
First, your test-bench should ensure a regular clock is driving
clk with a clock period of
100ns, and a 50% duty cycle.
Then, the testbench should allow to test a variety of operations
the sequence described
hereafter.
i) Reset: The test bench should first reset the register bank. The
reset is synchronous. It
should also set rrd1, rrd2, d, rwr, rwren to zero.
ii) Store1: store the value 0x55 to register RA
6. iii) Store2: store the value 0xAA to register RB
iii) Store3: store the value 0xFF to register RC
iv) Load1: get the content of register RA on q1 and RB on q2
v) Load2: get the content of register RC on q1 and RD on q2
In the coursework report:
i) Explain the testbench file you constructed, what it does, and
how it does it. In order to do
that, provide the complete source of the testbench, and in the
main text of your report
explain the testbench file. By “explaining the testbench”, we
ask you to first provide an
overall explanation of how you intend to simulate the system,
and then explain the purpose
of each of the VHDL constructs you are using to realise the
tests indicated above. Make
sure you explain where the Reset, Store1, Store2, Store3,
Load1, Load2 operations take
place.
Note: if you create the testbench from Vivado’s user interface, a
lot of default comments are
inserted by Vivado. Remove these, as they are not useful for
this coursework.
H7068 DIGITAL SYSTEMS AND MICROPROCESSOR
DESIGN: COURSEWORK 2019
7. ii) Provide a screen capture of the waveforms resulting from the
testbench. All signals must
be legible. Make sure that all the values in the waveforms are
legible and in hex. Note: do
not take photographs! Use a proper screen capture tool, such as
pressing the "Print Screen"
key. Explain what can be observed on these waveforms. Make
sure you highlight on the
waveform (e.g. with mspaint) where the operations Reset,
Store1, Store2, Store3, Load1,
Load2 operations take place.
All the register bank signals must be visible in the waveform.
[20 marks (10 marks for the testbench and associated
explanation, 10 marks for the
waveform and associated explanations; if the testbench does not
work, not marks will be
assigned)]
b) Consider an input signal (i.e. a square wave) which has a
maximum frequency of 1MHz. We
want to count how many times the input signal transitioned from
0 to 1.
Detail three approaches to count the number of transitions.
i) the first approach should be a pure digital circuit (i.e. no
processor).
ii) the second approach should consist only of a processor (UoS
educational processor).
iii) the third approach should be a combination of processor
(UoS educational processor)
8. and a digital circuit (e.g. interfaced on the external I/O bus),
both working together to acquire
the number of transitions. You have significant flexibility here
in finding an implementation
that offers an advantage compared to (i) and (ii) in some
interesting way. As a hint, consider
that the input signal could have potentially a much higher clock
frequency than the one at
which the processor operates.
In the report:
i) explain the implementation of your system in a way that
another engineer would
understand it. In particular, provide schematic for variant (i)
and (iii) and provide assembler
code for variant (ii) and (iii). Explain your choice, and how
your implementation works.
Make sure in the report that you do provide the code and
schematic, and explain in the core
text what the code or circuit does, and how.
ii) discuss the advantages and disadvantages of each approach.
[20 marks (5 marks per implementation with comments, 5 mark
for the indentification of
advantages and disadvantages]
c) The Sussex Educational Processor executes an instruction
every 3 clock cycles. Explain
why that is the case and specifically what happens during each
of these three clock cycles.
[5 marks]
9. d) Explain and justify what is the maximum addressable
memory for the processor using the
mov instruction (note that this is not the amount of available
memory, which was 32 bytes in
the labs; it's the maximum amount of memory which could be
‘touched’ by the processor).
[5 marks]
e) You are provided with the following VHDL code of a logic
gate:
H7068 DIGITAL SYSTEMS AND MICROPROCESSOR
DESIGN: COURSEWORK 2019
entity something is
port ( clk : in STD_LOGIC;
s : in STD_LOGIC;
r : in STD_LOGIC;
d : in STD_LOGIC;
q : out STD_LOGIC);
end something;
architecture Behavioral of something is
begin
process(clk)
begin
if s='1' then
q<='1';
else
if clk'event and clk='0' then
if r='1' then
q <= '0';
10. else
q <= not d;
end if;
end if;
end if;
end process;
end Behavioral;
The resulting logic gate is a variation of a type of gate
commonly used in digital systems.
Explain what is this logic gate and how it behaves.
[5 marks]
f) Write an assembler program that performs a loop exactly n
times, with the value n specified
on 8-bits on the external interface. Write down: i) the assembler
code; ii) an explanation of
what the assembler code does, line by line.
[10 marks (5 marks for the program, 5 for the explanations)]
g) Consider the program below. Explain line by line the
operation performed by the instruction
and the resulting register values for registers RA, RB, RC, RD.
Write the value that is in the
register after the execution of the instruction in the
corresponding column; if the value is
unknown indicated this with ??. Assume we do not know the
content of the registers on
program start.
RA RB RC RD
mov rb,32h . . . .
xor rd,rd . . . .
11. sub rd,rb . . . .
shr rb . . . .
asr rd . . . .
[5 marks (1 mark per correct line)]
h) You are provided with the following memory dump. Write
the assembler instructions
corresponding to this memory dump.
H7068 DIGITAL SYSTEMS AND MICROPROCESSOR
DESIGN: COURSEWORK 2019
Address Data
00 1330
02 3303
04 5770
06 B10A
08 B002
[5 marks (1 per correct instruction)]
i) Explain how many total number of ALU operations could be
realised in the UoS Educational
Processor if you modified the cpualu.vhd keeping the current
structure of the instruction
encoding, and provide an explanation for your answer.
[5 marks]
j) Consider the instruction "MOV [RB], RD" (assume
RA=08h,RB=55h,RC=37h,RD=A0h).
Assume we are shortly before the clock edge of the "execute"
12. cycle (i.e. at the next rising
edge the instruction will be executed).
By analyzing the VHDL code of the processor, explain what
happens inside the educational
processor to execute this instruction. Specifically, indicate the
state of the following signals
(or indicate if undefined):
instruction (in cpu.vhd)
rrd1 (port of cpuregbank in cpu.vhd)
rrd2 (port of cpuregbank in cpu.vhd)
rwr (port of cpuregbank in cpu.vhd)
d (port of cpuregbank in cpu.vhd)
reg1out (in cpu.vhd)
reg2out (in cpu.vhd)
source (in cpu.vhd)
regwren (in cpu.vhd)
flagwren (in cpu.vhd)
ram_we (in cpu.vhd)
ram_address (in cpu.vhd)
ram_datawr (in cpu.vhd)
op (port of cpualu in cpu.vhd)
a (port of cpualu in cpu.vhd)
b (port of cpualu in cpu.vhd)
aluqout (in cpu.vhd)
alufout (in cpu.vhd)
wrdata (in cpu.vhd)
finally, summarize the overall processor behavior with this
instruction.
[20 marks (1 mark per correct signal value, 1 mark for a correct
explanation)]
13. dffre1.txt
-- 8-bit register (D flip-flop) with synchronous enable and reset
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity dffre is
generic (N : integer);
port(
clk : in STD_LOGIC;
en : in STD_LOGIC;
rst: in STD_LOGIC;
d : in STD_LOGIC_VECTOR(N-1 downto 0);
q : out STD_LOGIC_VECTOR(N-1 downto 0)
);
end dffre;
14. architecture Behavioral of dffre is
begin
process(clk)
begin
if rising_edge(clk) then
if rst='1' then
q<=(others=>'0');
else
if en='1' then
q<=d;
end if;
end if;
end if;
end process;
end Behavioral;
16. begin
process(clk)
begin
if rising_edge(clk) then
last <= din;
end if;
end process;
dout <= din and not last;
end Behavioral;
hexto7seg1.txt
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use IEEE.std_logic_unsigned.ALL;
17. entity hexto7seg is
port(
clk: in std_logic;
d7: in std_logic_vector(3 downto 0);
d6: in std_logic_vector(3 downto 0);
d5: in std_logic_vector(3 downto 0);
d4: in std_logic_vector(3 downto 0);
d3: in std_logic_vector(3 downto 0);
d2: in std_logic_vector(3 downto 0);
d1: in std_logic_vector(3 downto 0);
d0: in std_logic_vector(3 downto 0);
blink: in std_logic_vector(7 downto 0);
q: out std_logic_vector(6 downto 0);
active : out std_logic_vector(7 downto 0)
);
end hexto7seg;
architecture Behavioral of hexto7seg is
18. signal a: std_logic;
signal b: std_logic;
signal c: std_logic;
signal d: std_logic;
signal qt: std_logic_vector(6 downto 0);
signal ctr: std_logic_vector(2 downto 0);
signal divider: std_logic_vector(25 downto 0);
begin
p1: process(clk)
begin
if rising_edge(clk) then
divider<=divider+1;
end if;
end process;
p2: process(clk)
begin
if rising_edge(clk) then
if divider(9 downto 0)="0000000000"
19. then
ctr<=ctr+1;
end if;
end if;
end process;
-- input mux
with ctr select
a <= d0(3) when "000",
d1(3) when "001",
d2(3) when "010",
d3(3) when "011",
d4(3) when "100",
d5(3) when "101",
d6(3) when "110",
d7(3) when others;
with ctr select
b <= d0(2) when "000",
d1(2) when "001",
20. d2(2) when "010",
d3(2) when "011",
d4(2) when "100",
d5(2) when "101",
d6(2) when "110",
d7(2) when others;
with ctr select
c <= d0(1) when "000",
d1(1) when "001",
d2(1) when "010",
d3(1) when "011",
d4(1) when "100",
d5(1) when "101",
d6(1) when "110",
d7(1) when others;
with ctr select
d <= d0(0) when "000",
d1(0) when "001",
21. d2(0) when "010",
d3(0) when "011",
d4(0) when "100",
d5(0) when "101",
d6(0) when "110",
d7(0) when others;
-- Output mux
with ctr select
active <= "11111110" when "000",
"11111101" when "001",
"11111011" when "010",
"11110111" when "011",
"11101111" when "100",
"11011111" when "101",
"10111111" when "110",
"01111111" when others;
22. -- Blinking
q(0) <= (blink(to_integer(unsigned(ctr))) and divider(25))
or qt(0);
q(1) <= (blink(to_integer(unsigned(ctr))) and divider(25))
or qt(1);
q(2) <= (blink(to_integer(unsigned(ctr))) and divider(25))
or qt(2);
q(3) <= (blink(to_integer(unsigned(ctr))) and divider(25))
or qt(3);
q(4) <= (blink(to_integer(unsigned(ctr))) and divider(25))
or qt(4);
q(5) <= (blink(to_integer(unsigned(ctr))) and divider(25))
or qt(5);
q(6) <= (blink(to_integer(unsigned(ctr))) and divider(25))
or qt(6);
qt(0) <= not ( (not a and not b and not c and not d )
or (not a and not b and c and not d)
or (not a and not b and c and d)
23. or (not a and b and not c and d)
or (not a and b and c and not d)
or (not a and b and c and d)
or (a and not b and not c and not d)
or (a and not b and not c and d)
or (a and not b and c and not d)
or (a and b and not c and not d)
or (a and b and c and not d)
or (a and b and c and d) );
qt(1) <= not ( (not a and not b and not c and not d)
or (not a and not b and not c and d)
or (not a and not b and c and not d)
or (not a and not b and c and c)
or (not a and b and not c and not d)
or (not a and b and c and d)
or (a and not b and not c and not d)
or (a and not b and not c and d)
24. or (a and not b and c and not d)
or (a and b and not c and d) );
qt(2) <= not ( (not a and not b and not c and not d)
or (not a and not b and not c and d)
or (not a and not b and c and d)
or (not a and b and not c and not d)
or (not a and b and not c and d)
or (not a and b and c and not d)
or (not a and b and c and d)
or (a and not b and not c and not d)
or (a and not b and not c and d)
or (a and not b and c and not d)
or (a and not b and c and d)
or (a and b and not c and d) );
qt(3) <= not ((not a and not b and not c and not d)
or (not a and not b and c and not d)
or (not a and not b and c and d)
25. or (not a and b and not c and d)
or (not a and b and c and not d)
or (a and not b and not c and not d)
or (a and not b and c and d)
or (a and b and not c and not d)
or (a and b and not c and d)
or (a and b and c and not d) );
--qt(4) <= not ((not a and not b and not c and not d)
-- or (not a and not b and c and not d)
-- or (not a and b and c and not d)
-- or (a and not b and not c and not d)
-- or (a and not b and c and not d)
-- or (a and not b and c and d)
-- or (a and b and not c and not d)
-- or (a and b and not c and d)
-- or (a and b and c and not d)
-- or (a and b and c and d) );
26. --qt(5) <= not ((not a and not b and not c and not d)
-- or (not a and b and not c and not d)
-- or (not a and b and not c and d)
-- or (not a and b and c and not d)
-- or (a and not b and not c and not d)
-- or (a and not b and not c and d)
-- or (a and not b and c and not d)
-- or (a and not b and c and d)
-- or (a and b and not c and not d)
-- or (a and b and c and not d)
-- or (a and b and c and d) );
--qt(6) <= not ((not a and not b and c and not d)
-- or (not a and not b and c and d)
-- or (not a and b and not c and not d)
-- or (not a and b and not c and d)
27. -- or (not a and b and c and not d)
-- or (a and not b and not c and not d)
-- or (a and not b and not c and d)
-- or (a and not b and c and not d)
-- or (a and not b and c and d)
-- or (a and b and not c and d)
-- or (a and b and c and not d)
-- or (a and b and c and d) );
-- Minimized expression:
qt(4) <= not( (a and b) or (a and c) or (c and not d) or (not
b and not d) );
qt(5) <= not( (b and not d) or (not a and b and not c) or (a
and not b) or (a and c) or (not c and not d) );
qt(6) <= not( (not a and b and not c) or (a and not b) or (a
and d) or (not b and c and d) or (c and not d) );
end Behavioral;
28. labcpu1.txt
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity main is
Port (
clk : in STD_LOGIC;
btnU : in STD_LOGIC;
btnD : in STD_LOGIC;
btnL : in STD_LOGIC;
btnC : in STD_LOGIC;
btnR : in STD_LOGIC;
btnCpuReset : in STD_LOGIC;
sw : in STD_LOGIC_VECTOR (15
downto 0);
led : out STD_LOGIC_VECTOR (15
downto 0);
29. seg : out STD_LOGIC_VECTOR(6 downto
0);
an : out STD_LOGIC_VECTOR(7 downto
0)
);
end main;
architecture Structural of main is
signal reset : STD_LOGIC;
-- clocks
signal clkmain : STD_LOGIC;
signal clkslow : STD_LOGIC;
30. signal cpu_ram_we : STD_LOGIC;
signal cpu_ram_address : STD_LOGIC_VECTOR(4
downto 0);
signal cpu_ram_datawr : STD_LOGIC_VECTOR(7 downto
0);
signal cpu_ram_datard : STD_LOGIC_VECTOR(7 downto
0);
signal ramedit_address : STD_LOGIC_VECTOR(4 downto
0);
signal ramedit_data : STD_LOGIC_VECTOR(7 downto 0);
signal ramedit_enable : STD_LOGIC;
signal ramedit_we : STD_LOGIC;
-- Display signals
signal display_d7 : STD_LOGIC_VECTOR(3 downto 0);
signal display_d6 : STD_LOGIC_VECTOR(3 downto 0);
signal display_d5 : STD_LOGIC_VECTOR(3 downto 0);
signal display_d4 : STD_LOGIC_VECTOR(3 downto 0);
signal display_d3 : STD_LOGIC_VECTOR(3 downto 0);
31. signal display_d2 : STD_LOGIC_VECTOR(3 downto 0);
signal display_d1 : STD_LOGIC_VECTOR(3 downto 0);
signal display_d0 : STD_LOGIC_VECTOR(3 downto 0);
signal display_blink : STD_LOGIC_VECTOR(7 downto
0);
signal cpu_d0, cpu_d1, cpu_d2, cpu_d3, cpu_d4, cpu_d5,
cpu_d6, cpu_d7 : STD_LOGIC_VECTOR(3 downto 0);
-- RAM signals
signal ramclk : STD_LOGIC;
signal ram_address : STD_LOGIC_VECTOR(4 downto 0);
signal ram_datain : STD_LOGIC_VECTOR(7 downto 0);
signal ram_we : STD_LOGIC;
signal ram_dataout : STD_LOGIC_VECTOR(7 downto 0);
-- debouncing
signal btnUd,btnDd,btnLd,btnCd,btnRd,btnCpuResetd :
STD_LOGIC;
signal sw15d,sw13d : STD_LOGIC;
32. -- edge detect
signal btnUde,btnDde,btnLde,btnRde : STD_LOGIC;
-- Only for CPU debugging
signal dbg_qa : STD_LOGIC_VECTOR(7 downto 0);
signal dbg_qb : STD_LOGIC_VECTOR(7 downto 0);
signal dbg_qc : STD_LOGIC_VECTOR(7 downto 0);
signal dbg_qd : STD_LOGIC_VECTOR(7 downto 0);
signal dbg_instr : STD_LOGIC_VECTOR(15 downto 0);
signal dbg_seq : STD_LOGIC_VECTOR(1 downto 0);
signal dbg_flags : STD_LOGIC_VECTOR(3 downto 0);
begin
-- Debouncing
comp_deb1 : entity work.debounce port
map(clk=>clk,button=>btnC,result=>btnCd);
comp_deb2 : entity work.debounce port
map(clk=>clk,button=>btnU,result=>btnUd);
comp_deb3 : entity work.debounce port
map(clk=>clk,button=>btnD,result=>btnDd);
33. comp_deb4 : entity work.debounce port
map(clk=>clk,button=>btnL,result=>btnLd);
comp_deb5 : entity work.debounce port
map(clk=>clk,button=>btnR,result=>btnRd);
comp_deb6 : entity work.debounce port
map(clk=>clk,button=>btnCpuReset,result=>btnCpuResetd);
comp_deb7 : entity work.debounce port
map(clk=>clk,button=>sw(15),result=>sw15d);
comp_deb8 : entity work.debounce port
map(clk=>clk,button=>sw(13),result=>sw13d);
-- Edge detectors on some buttons (for RAM editor)
comp_edg1 : entity work.edgedetect port
map(clk=>clk,din=>btnLd,dout=>btnLde);
comp_edg2 : entity work.edgedetect port
map(clk=>clk,din=>btnRd,dout=>btnRde);
comp_edg3 : entity work.edgedetect port
map(clk=>clk,din=>btnUd,dout=>btnUde);
comp_edg4 : entity work.edgedetect port
map(clk=>clk,din=>btnDd,dout=>btnDde);
-- slow clock
34. --
comp_clk : entity work.clkdiv generic map(N=>25) port
map(clkin=>clk,clkout=>clkslow);
-- Reset
--
reset <= not btnCpuResetd;
-- Toggle the RAM edit mode according to sw15d
--
ramedit_enable <= sw15d;
-- Display debug status on LEDs
--
led(15) <= ramedit_enable;
led(14) <= clkmain;
led(13 downto 12) <= dbg_seq;
led(11 downto 8) <= dbg_flags;
35. -- Display multiplexers: toggle between ram edit and cpu
mode
display_blink <=
"00"&ramedit_enable&ramedit_enable&ramedit_enable&ramedi
t_enable&ramedit_enable&ramedit_enable;
display_d7 <= "0000" when ramedit_enable='1' else
cpu_d7;
display_d6 <= "0000" when ramedit_enable='1' else
cpu_d6;
display_d5 <= "000"&ram_address(4 downto 4) when
ramedit_enable='1' else cpu_d5;
display_d4 <= ram_address(3 downto 0) when
ramedit_enable='1' else cpu_d4;
display_d3 <= sw(7 downto 4) when ramedit_enable='1'
else cpu_d3;
display_d2 <= sw(3 downto 0) when ramedit_enable='1'
else cpu_d2;
display_d1 <= ram_dataout(7 downto 4) when
ramedit_enable='1' else cpu_d1;
display_d0 <= ram_dataout(3 downto 0) when
ramedit_enable='1' else cpu_d0;
38. --led(15)<=clkmain;
clkmain <= not ramedit_enable and( (btnCd and not
sw13d) or (clkslow and sw13d));
-- Instantiate RAM
-- RAM clock is either board clock in edit mode, or manual
clock
ramclk <= clk when sw15d='1' else clkmain;
comp3: entity work.ram generic map(N=>5) port
map(clk=>ramclk,address=>ram_address,data=>ram_datain,we=
>ram_we,q=>ram_dataout);
-- Instantiate the RAM editor
comp_ramedit:
entity work.ramedit generic map(N=>5) port
map(clk=>clk,rst=>reset,btnU=>btnUde,btnD=>btnDde,btnL=>
btnLde,btnR=>btnRde,din=>sw,
we=>ramedit_we,address=>ramedit_address,data=>ramedit
39. _data);
-- Multiplex the editor and the CPU to the RAM
--
ram_we <= ramedit_we when ramedit_enable='1' else
cpu_ram_we;
ram_address <= ramedit_address when ramedit_enable='1'
else cpu_ram_address;
ram_datain <= ramedit_data when ramedit_enable='1' else
cpu_ram_datawr;
-- Instantiate the CPU
comp_cpu:
entity work.CPU generic map(N=>5)
port
map(clk=>clkmain,rst=>reset,ext_in=>sw(7 downto
0),ext_out=>led(7 downto 0),
ram_we=>cpu_ram_we,ram_address=>cpu_ram_address,ra
m_datawr=>cpu_ram_datawr,ram_datard=>ram_dataout,
41. q: OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END ram;
ARCHITECTURE rtl OF ram IS
TYPE mem IS ARRAY(0 TO 2**N-1) OF std_logic_vector(7
DOWNTO 0);
SIGNAL ram_block : mem := (
-- Put the initial content of the memory here. Note: provide
exactly 32 bytes
X"00",
X"00",
X"00",
X"00",
X"00",
X"00",
X"00",
X"00",
X"00",
X"00",
X"00",
X"00",
X"00",
43. IF we = '1' THEN
ram_block(to_integer(unsigned(address))) <= data;
END IF;
END IF;
END PROCESS;
q <= ram_block(to_integer(unsigned(address)));
END rtl;
ramedit1.txt
-- RAM editor
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity ramedit is
generic(N : integer);
port(
clk : in STD_LOGIC;
44. rst : in STD_LOGIC;
btnU : in STD_LOGIC;
btnD : in STD_LOGIC;
btnL : in STD_LOGIC;
btnR : in STD_LOGIC;
din : in STD_LOGIC_VECTOR(15 downto 0);
we : out STD_LOGIC;
address : out STD_LOGIC_VECTOR(N-1
downto 0);
data : out STD_LOGIC_VECTOR(7 downto 0)
);
end ramedit;
architecture Behavioral of ramedit is
-- Register with the address we currently wish to edit
signal address_edit : STD_LOGIC_VECTOR(N-1 downto
0);
begin
process(clk,rst)
45. begin
if rising_edge(clk) then
if rst='1' then
address_edit<=(others=>'0');
else
if btnU='1' and btnD='0' then
address_edit <= address_edit+1;
elsif btnU='0' and btnD='1' then
address_edit <= address_edit-1;
elsif btnL='1' then
address_edit <= din(8+N-1 downto 8);
end if;
end if;
end if;
end process;
we <= btnR;
address <= address_edit;
46. data <= din(7 downto 0);
end Behavioral;
clkdiv1.txt
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity clkdiv is
generic(N : integer);
port ( clkin : in STD_LOGIC;
clkout : out STD_LOGIC
);
end clkdiv;
architecture Behavioral of clkdiv is
signal divider : STD_LOGIC_VECTOR(N-1 downto 0);
48. use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity cpu is
generic(N : integer);
port(
clk : in STD_LOGIC;
rst : in STD_LOGIC;
ext_in : in STD_LOGIC_VECTOR(7 downto 0);
ext_out : out STD_LOGIC_VECTOR(7 downto
0);
ram_we : out STD_LOGIC;
ram_address : out STD_LOGIC_VECTOR(N-1
downto 0);
ram_datawr : out STD_LOGIC_VECTOR(7
downto 0);
ram_datard : in STD_LOGIC_VECTOR(7
downto 0);
-- Only for debugging
49. dbg_qa : out STD_LOGIC_VECTOR(7 downto
0);
dbg_qb : out STD_LOGIC_VECTOR(7 downto
0);
dbg_qc : out STD_LOGIC_VECTOR(7 downto
0);
dbg_qd : out STD_LOGIC_VECTOR(7 downto
0);
dbg_instr : out STD_LOGIC_VECTOR(15
downto 0);
dbg_seq : out STD_LOGIC_VECTOR(1 downto
0);
dbg_flags : out STD_LOGIC_VECTOR(3
downto 0)
);
end cpu;
architecture Behavioral of cpu is
-- Instruction
50. signal instruction : STD_LOGIC_VECTOR(15 downto 0);
-- Helper
signal source : STD_LOGIC_VECTOR(7 downto 0);
signal wrdata : STD_LOGIC_VECTOR(7 downto 0);
-- register bank
signal regwren : STD_LOGIC;
signal reg1out : STD_LOGIC_VECTOR(7 downto 0);
signal reg2out : STD_LOGIC_VECTOR(7 downto 0);
-- flags
signal flagwren : STD_LOGIC;
signal flags : STD_LOGIC_VECTOR(3 downto 0); -- zf,
ovf, cf, sf
signal zf,ovf,cf,sf : STD_LOGIC;
-- fetch/execute signals
signal seq : STD_LOGIC_VECTOR(1 downto 0);
51. signal execute,fetch,fetchh,fetchl : STD_LOGIC;
-- Instruction pointer
signal ip: STD_LOGIC_VECTOR(N-1 downto 0);
signal ipnext: STD_LOGIC_VECTOR(N-1 downto 0);
-- ALU input and output signals
signal aluqout: STD_LOGIC_VECTOR(7 downto 0);
signal alufout : STD_LOGIC_VECTOR(3 downto 0);
-- Jumps
signal jump : STD_LOGIC;
signal jumpip: STD_LOGIC_VECTOR(N-1 downto 0);
signal jumpconditionvalid : STD_LOGIC;
-- External interface
signal ext_wren : STD_LOGIC;
52. -- Debug signals
--signal tdbg_qa,tdbg_qb,tdbg_qc,tdbg_qd :
STD_LOGIC_VECTOR(7 downto 0);
begin
---------------------------------------------------------------------
------------------
-- Fetch/Execute -- Fetch/Execute -- Fetch/Execute --
Fetch/Execute -- Fetch/Execute --
---------------------------------------------------------------------
------------------
-- Instantiate a fetch/exec sequencer. Seq is 00 for load1,
01 for load2, 10 for execute
comp_seq: entity work.cpusequencer port
map(clk=>clk,rst=>rst,en=>'1',seq=>seq);
-- Binary to one hot
fetchh <= '1' when seq="00" else
'0';
53. fetchl <= '1' when seq="01" else
'0';
execute <= '1' when seq="10" else
'0';
fetch <= fetchl or fetchh;
-- Instantiate two 8-bit registers to store the 16-bit
instruction during the fetchl and fetchh cycles.
comp_instrh: entity work.dffre generic map(N=>8) port
map(clk=>clk,rst=>rst,en=>fetchh,d=>ram_datard,q=>instructio
n(15 downto 8));
comp_instrl: entity work.dffre generic map(N=>8) port
map(clk=>clk,rst=>rst,en=>fetchl,d=>ram_datard,q=>instructio
n(7 downto 0));
---------------------------------------------------------------------
------------------
-- Instruction pointer
---------------------------------------------------------------------
------------------
comp_ip: entity work.dffre generic map(N=>N) port
map(clk=>clk,rst=>rst,en=>'1',d=>ipnext,q=>ip);
54. ipnext <= ip+1 when fetch='1' else
ip when jump='0' else
jumpip;
---------------------------------------------------------------------
------------------
-- Register bank -- Register bank -- Register bank --
Register bank -- Register bank --
---------------------------------------------------------------------
------------------
-- Instantiate the register bank
-- Always map the register 1 and register 2 to the source
and destination registers in the instruction fields
-- Always map the write register to destination register in
instruction field.
-- Always map the write input to wrdata
comp_regs: entity work.cpuregbank port
55. map(clk=>clk,rrd1=>instruction(9 downto
8),rrd2=>instruction(1 downto 0),rwr=>instruction(9 downto
8),rwren=>regwren,rst=>rst,d=>wrdata,q1=>reg1out,q2=>reg2o
ut,
dbg_qa=>dbg_qa,dbg_qb=>dbg_qb,dbg_qc=>dbg_qc,dbg_
qd=>dbg_qd);
-- Write to register for move instructions with direct
destination, or ALU instructions except cmp.
regwren <= '1' when execute='1' and
instruction(15 downto 13) = "000" and instruction(11)='0' else
-- opcode 000 (move)
'1' when execute='1' and
instruction(15 downto 13) = "001" else
-- opcode 001
(add,sub,and,or)
'1' when execute='1' and
instruction(15 downto 13) = "010" and instruction(11 downto
10) /= "01" else -- opcode 010 (all except cmp)
'1' when execute='1' and
instruction(15 downto 13) = "011" else
-- opcode 011
'1' when execute='1' and
instruction(15 downto 13) = "110" and instruction(11 downto
10) = "01" else -- opcode 110 (io)
'0';
56. ---------------------------------------------------------------------
-----------------------
-- Helper -- Helper -- Helper -- Helper -- Helper -- Helper
-- Helper -- Helper -- Helper --
---------------------------------------------------------------------
-----------------------
-- Almost all instructions using a source have register or
immediate mode. We
source <= reg2out when instruction(12)='0' else
instruction(7 downto 0);
---------------------------------------------------------------------
----------
-- ALU -- ALU -- ALU -- ALU -- ALU -- ALU -- ALU --
ALU -- ALU -- ALU -- ALU --
---------------------------------------------------------------------
----------
-- Instantiate ALU
57. comp_alu: entity work.cpualu port
map(clk=>clk,rst=>rst,op=>instruction(14 downto
10),a=>reg1out,b=>source,q=>aluqout,f=>alufout);
---------------------------------------------------------------------
--------------
-- Flags -- Flags -- Flags -- Flags -- Flags -- Flags -- Flags
-- Flags -- Flags --
---------------------------------------------------------------------
--------------
-- instantiate register to store the flags
comp_flags: entity work.dffre generic map(N=>4) port
map(clk=>clk,rst=>rst,en=>flagwren,d=>alufout,q=>flags);
-- When to write the flags: execute phase and compare
instruction
flagwren <= '1' when execute='1' and instruction(15
downto 13)="010" and instruction(11 downto 10)="01"
else '0';
-- Individual signals for each flag
zf <= flags(3);
ovf <= flags(2);
cf <= flags(1);
58. sf <= flags(0);
---------------------------------------------------------------------
--------------
-- Jump -- Jump -- Jump -- Jump -- Jump -- Jump -- Jump -
- Jump -- Jump -- Jump --
---------------------------------------------------------------------
--------------
-- Jump destinatinon is register or immediate
jumpip <= source(N-1 downto 0);
-- Do jump when the instruction is a jump and the jump
condition is met
jump <= '1' when instruction(15 downto 13) = "101" and
jumpconditionvalid='1' else
'0';
-- Jump condition
jumpconditionvalid <= '1' when instruction(11 downto 8)
= "0000" else --
Unconditional jump
'1' when
instruction(11 downto 8) = "0001" and zf='1' else
-- je/jz
'1' when
59. instruction(11 downto 8) = "1001" and zf='0' else
-- jne/jnz
'1' when
instruction(11 downto 8) = "0010" and zf='0' and cf='0' else --
ja
'1' when
instruction(11 downto 8) = "1011" and zf='0' and cf='1' else --
jb
'0';
---------------------------------------------------------------------
------------------
-- RAM interface -- RAM interface -- RAM interface --
RAM interface -- RAM interface --
---------------------------------------------------------------------
------------------
-- ram address to read instruction and read or write data
ram_address <= ip when fetch='1' else
reg2out(N-1 downto 0) when
instruction(15 downto 10)="000001" else
instruction(N-1 downto 0) when
instruction(15 downto 10)="000101" else
60. reg1out(N-1 downto 0) when
instruction(15 downto 10)="000010" else
reg1out(N-1 downto 0) when
instruction(15 downto 10)="000110" else
(others=>'0');
--"00000";
-- Enable write
ram_we <= '1' when execute='1' and instruction(15
downto 13)="000" and instruction(11 downto 10)="10" else
'0';
-- Data to write
ram_datawr <= wrdata;
---------------------------------------------------------------------
---------------------
-- External interface -- External interface -- External
interface -- External interface --
---------------------------------------------------------------------
---------------------
61. -- Instantiate a register to hold the output interface data
comp_regextout : entity work.dffre generic map (N=>8)
port
map(clk=>clk,rst=>rst,en=>ext_wren,d=>source,q=>ext_out);
ext_wren <= '1' when execute='1' and instruction(15
downto 13) = "110" and instruction(11 downto 10)="00" else
'0';
---------------------------------------------------------------------
-----------------
-- Write data -- Write data -- Write data -- Write data --
Write data -- Write data --
---------------------------------------------------------------------
-----------------
-- Data may be written to ram or memory. The enable
signals in the ram and register instances
-- control whether the write occurs.
-- Here we define what to write.
wrdata <= source when instruction(15 downto 13) = "000"
and instruction(11 downto 10)="00" else -- Move with
register or immediate as source
62. source when instruction(15 downto
13) = "000" and instruction(11 downto 10)="10" else
-- Move with register or immediate as source
ram_datard when instruction(15
downto 13) = "000" and instruction(11 downto 10)="01" else
-- Move with memory as source
aluqout when instruction(15 downto
13) = "001" else -- ALU
aluqout when instruction(15 downto
13) = "010" else -- ALU
aluqout when instruction(15 downto
13) = "011" else -- ALU
ext_in when instruction(15 downto 13)
= "110" and instruction(11 downto 10)="01" else --
Instruction in: read external input
"00000000";
-- Only for debugging
dbg_instr <= instruction;
dbg_seq <= seq;
dbg_flags <= flags;
63. end Behavioral;
cpualu1.txt
-- ALU
-- The ALU uses 1 or 2 operands
-- The opcode are bits 14,13,12,11,10 of the instruction
-- a: input A of ALU
-- b: input B of ALU (not used for single operand instructions)
-- q: result (except for compare which is not used)
-- f: flag vectors with zero flag, overflow flag, carry flag and
sign flag.
64. library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity cpualu is
port (
clk : in STD_LOGIC;
rst : in STD_LOGIC;
op : in STD_LOGIC_VECTOR(4 downto 0);
a : in STD_LOGIC_VECTOR(7 downto 0);
b : in STD_LOGIC_VECTOR(7 downto 0);
q : out STD_LOGIC_VECTOR(7 downto 0);
f : out STD_LOGIC_VECTOR(3 downto 0)
);
end cpualu;
architecture Behavioral of cpualu is
65. signal sub : STD_LOGIC_VECTOR(8 downto 0); -- Do
subtraction on 9 bits to obtain the carry
signal r: STD_LOGIC_VECTOR(7 downto 0); -- ALU
result
signal zf,ovf,cf,sf : STD_LOGIC;
begin
--comp_rng: entity work.rng port map(clk=>clk,rst=>rst
sub <= ('0'&a) - ('0'&b);
r <= a+b when op(4 downto 3)="01" and op(1 downto
0)="00" else
sub(7 downto 0) when op(4 downto 3)="01"
and op(1 downto 0)="01" else
a and b when op(4 downto 3)="01" and
op(1 downto 0)="10" else
a or b when op(4 downto 3)="01" and op(1
downto 0)="11" else
a xor b when op(4 downto 3)="10" and
op(1 downto 0)="00" else
66. not a when op(4 downto 0)="11000" else
'0'&a(7 downto 1) when op(4 downto
0)="11001" else
a(0)&a(7 downto 1) when op(4 downto
0)="11010" else
a(7)&a(7 downto 1) when op(4 downto
0)="11011" else
a(6 downto 0)&a(7) when op(4 downto
0)="11100" else
"00000000";
sf <= sub(7);
zf <= not(sub(7) or sub(6) or sub(5) or sub(4) or sub(3) or
sub(2) or sub(1) or sub(0));
cf <= sub(8);
ovf <= (not a(7) and b(7) and sub(7)) or (a(7) and not b(7)
and not sub(7));
f<=zf&ovf&cf&sf;
q<=r;
67. end Behavioral;
cpuregbank1.txt
-- CPU register banks holding the 4 CPU registers.
-- This is used to simplify the reading and writing to registers
-- by allowing to address them with a 2-bit address and enable
signal.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity cpuregbank is
port(
clk : in STD_LOGIC;
rrd1 : in STD_LOGIC_VECTOR(1 downto 0);
rrd2 : in STD_LOGIC_VECTOR(1 downto 0);
rwr : in STD_LOGIC_VECTOR(1 downto 0);
rwren : in STD_LOGIC;
68. rst : in STD_LOGIC;
d : in STD_LOGIC_VECTOR(7 downto 0);
q1 : out STD_LOGIC_VECTOR(7 downto 0);
q2 : out STD_LOGIC_VECTOR(7 downto 0);
-- Only for debugging
dbg_qa : out STD_LOGIC_VECTOR(7 downto 0);
dbg_qb : out STD_LOGIC_VECTOR(7 downto 0);
dbg_qc : out STD_LOGIC_VECTOR(7 downto 0);
dbg_qd : out STD_LOGIC_VECTOR(7 downto 0)
);
end cpuregbank;
architecture Behavioral of cpuregbank is
signal enables: STD_LOGIC_VECTOR(3 downto 0);
signal qa,qb,qc,qd: STD_LOGIC_VECTOR(7 downto 0);
begin
69. ra: entity work.dffre generic map (N=>8) port
map(clk=>clk,en=>enables(0),rst=>rst,d=>d,q=>qa);
rb: entity work.dffre generic map (N=>8) port
map(clk=>clk,en=>enables(1),rst=>rst,d=>d,q=>qb);
rc: entity work.dffre generic map (N=>8) port
map(clk=>clk,en=>enables(2),rst=>rst,d=>d,q=>qc);
rd: entity work.dffre generic map (N=>8) port
map(clk=>clk,en=>enables(3),rst=>rst,d=>d,q=>qd);
with rwr select
enables <= "0001" and
rwren&rwren&rwren&rwren when "00",
"0010" and
rwren&rwren&rwren&rwren when "01",
"0100" and
rwren&rwren&rwren&rwren when "10",
"1000" and
rwren&rwren&rwren&rwren when others;
with rrd1 select
q1 <= qa when "00",
qb when "01",
70. qc when "10",
qd when others;
with rrd2 select
q2 <= qa when "00",
qb when "01",
qc when "10",
qd when others;
-- Only for debugging
dbg_qa <= qa;
dbg_qb <= qb;
dbg_qc <= qc;
dbg_qd <= qd;
end Behavioral;
71. cpusequencer1.txt
-- Generates the CPU state sequence seq: ld1 (00), ld2 (01),
exec (10)
-- Implementation with a D FF with synchronous reset and
enable
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity cpusequencer is
port(
clk : in STD_LOGIC;
rst : in STD_LOGIC;
en : in STD_LOGIC;
seq : out STD_LOGIC_VECTOR(1 downto 0)
);
end cpusequencer;
72. architecture Behavioral of cpusequencer is
signal s : STD_LOGIC_VECTOR(1 downto 0);
begin
process(clk,rst)
begin
if rising_edge(clk) then
if rst='1' then
s<="00";
else
if en='1' then
if s="10" then
s <= "00";
else
s <= s+1;
end if;
end if;
end if;
73. end if;
end process;
seq <= s;
end Behavioral;
debounce1.txt
---------------------------------------------------------------------------
-----
--
-- FileName: debounce.vhd
-- Dependencies: none
-- Design Software: Quartus II 32-bit Version 11.1 Build 173
SJ Full Version
--
-- HDL CODE IS PROVIDED "AS IS." DIGI-KEY
EXPRESSLY DISCLAIMS ANY
-- WARRANTY OF ANY KIND, WHETHER EXPRESS OR
IMPLIED, INCLUDING BUT NOT
74. -- LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A
-- PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN
NO EVENT SHALL DIGI-KEY
-- BE LIABLE FOR ANY INCIDENTAL, SPECIAL,
INDIRECT OR CONSEQUENTIAL
-- DAMAGES, LOST PROFITS OR LOST DATA, HARM TO
YOUR EQUIPMENT, COST OF
-- PROCUREMENT OF SUBSTITUTE GOODS,
TECHNOLOGY OR SERVICES, ANY CLAIMS
-- BY THIRD PARTIES (INCLUDING BUT NOT LIMITED
TO ANY DEFENSE THEREOF),
-- ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION,
OR OTHER SIMILAR COSTS.
--
-- Version History
-- Version 1.0 3/26/2012 Scott Larson
-- Initial Public Release
--
---------------------------------------------------------------------------
-----
75. LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
ENTITY debounce IS
GENERIC(
counter_size : INTEGER := 19); --counter size (19 bits
gives 10.5ms with 50MHz clock)
PORT(
clk : IN STD_LOGIC; --input clock
button : IN STD_LOGIC; --input signal to be debounced
result : OUT STD_LOGIC); --debounced signal
END debounce;
ARCHITECTURE logic OF debounce IS
SIGNAL flipflops : STD_LOGIC_VECTOR(1 DOWNTO 0);
--input flip flops
SIGNAL counter_set : STD_LOGIC; --sync reset
to zero
76. SIGNAL counter_out : STD_LOGIC_VECTOR(counter_size
DOWNTO 0) := (OTHERS => '0'); --counter output
BEGIN
counter_set <= flipflops(0) xor flipflops(1); --determine
when to start/reset counter
PROCESS(clk)
BEGIN
IF(clk'EVENT and clk = '1') THEN
flipflops(0) <= button;
flipflops(1) <= flipflops(0);
If(counter_set = '1') THEN --reset counter
because input is changing
counter_out <= (OTHERS => '0');
ELSIF(counter_out(counter_size) = '0') THEN --stable input
time is not yet met
counter_out <= counter_out + 1;
ELSE --stable input time is met
result <= flipflops(1);
77. END IF;
END IF;
END PROCESS;
END logic;
labcpu/clkdiv.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity clkdiv is
generic(N : integer);
port ( clkin : in STD_LOGIC;
clkout : out STD_LOGIC
);
end clkdiv;
architecture Behavioral of clkdiv is
78. signal divider : STD_LOGIC_VECTOR(N-1 downto 0);
begin
process(clkin)
begin
if rising_edge(clkin) then
divider<=divider+1;
end if;
end process;
clkout<=divider(N-1);
end Behavioral;
labcpu/cpu.vhd
---------------------------------------------------------------------------
-------
79. library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity cpu is
generic(N : integer);
port(
clk : in STD_LOGIC;
rst : in STD_LOGIC;
ext_in : in STD_LOGIC_VECTOR(7 downto 0);
ext_out : out STD_LOGIC_VECTOR(7 downto
0);
ram_we : out STD_LOGIC;
ram_address : out STD_LOGIC_VECTOR(N-1
downto 0);
ram_datawr : out STD_LOGIC_VECTOR(7
downto 0);
ram_datard : in STD_LOGIC_VECTOR(7
downto 0);
80. -- Only for debugging
dbg_qa : out STD_LOGIC_VECTOR(7 downto
0);
dbg_qb : out STD_LOGIC_VECTOR(7 downto
0);
dbg_qc : out STD_LOGIC_VECTOR(7 downto
0);
dbg_qd : out STD_LOGIC_VECTOR(7 downto
0);
dbg_instr : out STD_LOGIC_VECTOR(15
downto 0);
dbg_seq : out STD_LOGIC_VECTOR(1 downto
0);
dbg_flags : out STD_LOGIC_VECTOR(3
downto 0)
);
end cpu;
architecture Behavioral of cpu is
-- Instruction
81. signal instruction : STD_LOGIC_VECTOR(15 downto 0);
-- Helper
signal source : STD_LOGIC_VECTOR(7 downto 0);
signal wrdata : STD_LOGIC_VECTOR(7 downto 0);
-- register bank
signal regwren : STD_LOGIC;
signal reg1out : STD_LOGIC_VECTOR(7 downto 0);
signal reg2out : STD_LOGIC_VECTOR(7 downto 0);
-- flags
signal flagwren : STD_LOGIC;
signal flags : STD_LOGIC_VECTOR(3 downto 0); -- zf,
ovf, cf, sf
signal zf,ovf,cf,sf : STD_LOGIC;
-- fetch/execute signals
82. signal seq : STD_LOGIC_VECTOR(1 downto 0);
signal execute,fetch,fetchh,fetchl : STD_LOGIC;
-- Instruction pointer
signal ip: STD_LOGIC_VECTOR(N-1 downto 0);
signal ipnext: STD_LOGIC_VECTOR(N-1 downto 0);
-- ALU input and output signals
signal aluqout: STD_LOGIC_VECTOR(7 downto 0);
signal alufout : STD_LOGIC_VECTOR(3 downto 0);
-- Jumps
signal jump : STD_LOGIC;
signal jumpip: STD_LOGIC_VECTOR(N-1 downto 0);
signal jumpconditionvalid : STD_LOGIC;
-- External interface
signal ext_wren : STD_LOGIC;
83. -- Debug signals
--signal tdbg_qa,tdbg_qb,tdbg_qc,tdbg_qd :
STD_LOGIC_VECTOR(7 downto 0);
begin
---------------------------------------------------------------------
------------------
-- Fetch/Execute -- Fetch/Execute -- Fetch/Execute --
Fetch/Execute -- Fetch/Execute --
---------------------------------------------------------------------
------------------
-- Instantiate a fetch/exec sequencer. Seq is 00 for load1,
01 for load2, 10 for execute
comp_seq: entity work.cpusequencer port
map(clk=>clk,rst=>rst,en=>'1',seq=>seq);
-- Binary to one hot
fetchh <= '1' when seq="00" else
84. '0';
fetchl <= '1' when seq="01" else
'0';
execute <= '1' when seq="10" else
'0';
fetch <= fetchl or fetchh;
-- Instantiate two 8-bit registers to store the 16-bit
instruction during the fetchl and fetchh cycles.
comp_instrh: entity work.dffre generic map(N=>8) port
map(clk=>clk,rst=>rst,en=>fetchh,d=>ram_datard,q=>instructio
n(15 downto 8));
comp_instrl: entity work.dffre generic map(N=>8) port
map(clk=>clk,rst=>rst,en=>fetchl,d=>ram_datard,q=>instructio
n(7 downto 0));
---------------------------------------------------------------------
------------------
-- Instruction pointer
---------------------------------------------------------------------
------------------
comp_ip: entity work.dffre generic map(N=>N) port
85. map(clk=>clk,rst=>rst,en=>'1',d=>ipnext,q=>ip);
ipnext <= ip+1 when fetch='1' else
ip when jump='0' else
jumpip;
---------------------------------------------------------------------
------------------
-- Register bank -- Register bank -- Register bank --
Register bank -- Register bank --
---------------------------------------------------------------------
------------------
-- Instantiate the register bank
-- Always map the register 1 and register 2 to the source
and destination registers in the instruction fields
-- Always map the write register to destination register in
instruction field.
-- Always map the write input to wrdata
86. comp_regs: entity work.cpuregbank port
map(clk=>clk,rrd1=>instruction(9 downto
8),rrd2=>instruction(1 downto 0),rwr=>instruction(9 downto
8),rwren=>regwren,rst=>rst,d=>wrdata,q1=>reg1out,q2=>reg2o
ut,
dbg_qa=>dbg_qa,dbg_qb=>dbg_qb,dbg_qc=>dbg_qc,dbg_
qd=>dbg_qd);
-- Write to register for move instructions with direct
destination, or ALU instructions except cmp.
regwren <= '1' when execute='1' and
instruction(15 downto 13) = "000" and instruction(11)='0' else
-- opcode 000 (move)
'1' when execute='1' and
instruction(15 downto 13) = "001" else
-- opcode 001
(add,sub,and,or)
'1' when execute='1' and
instruction(15 downto 13) = "010" and instruction(11 downto
10) /= "01" else -- opcode 010 (all except cmp)
'1' when execute='1' and
instruction(15 downto 13) = "011" else
-- opcode 011
'1' when execute='1' and
instruction(15 downto 13) = "110" and instruction(11 downto
10) = "01" else -- opcode 110 (io)
87. '0';
---------------------------------------------------------------------
-----------------------
-- Helper -- Helper -- Helper -- Helper -- Helper -- Helper
-- Helper -- Helper -- Helper --
---------------------------------------------------------------------
-----------------------
-- Almost all instructions using a source have register or
immediate mode. We
source <= reg2out when instruction(12)='0' else
instruction(7 downto 0);
---------------------------------------------------------------------
----------
-- ALU -- ALU -- ALU -- ALU -- ALU -- ALU -- ALU --
ALU -- ALU -- ALU -- ALU --
---------------------------------------------------------------------
----------
-- Instantiate ALU
88. comp_alu: entity work.cpualu port
map(clk=>clk,rst=>rst,op=>instruction(14 downto
10),a=>reg1out,b=>source,q=>aluqout,f=>alufout);
---------------------------------------------------------------------
--------------
-- Flags -- Flags -- Flags -- Flags -- Flags -- Flags -- Flags
-- Flags -- Flags --
---------------------------------------------------------------------
--------------
-- instantiate register to store the flags
comp_flags: entity work.dffre generic map(N=>4) port
map(clk=>clk,rst=>rst,en=>flagwren,d=>alufout,q=>flags);
-- When to write the flags: execute phase and compare
instruction
flagwren <= '1' when execute='1' and instruction(15
downto 13)="010" and instruction(11 downto 10)="01"
else '0';
-- Individual signals for each flag
zf <= flags(3);
ovf <= flags(2);
cf <= flags(1);
89. sf <= flags(0);
---------------------------------------------------------------------
--------------
-- Jump -- Jump -- Jump -- Jump -- Jump -- Jump -- Jump -
- Jump -- Jump -- Jump --
---------------------------------------------------------------------
--------------
-- Jump destinatinon is register or immediate
jumpip <= source(N-1 downto 0);
-- Do jump when the instruction is a jump and the jump
condition is met
jump <= '1' when instruction(15 downto 13) = "101" and
jumpconditionvalid='1' else
'0';
-- Jump condition
jumpconditionvalid <= '1' when instruction(11 downto 8)
= "0000" else --
Unconditional jump
'1' when
instruction(11 downto 8) = "0001" and zf='1' else
-- je/jz
90. '1' when
instruction(11 downto 8) = "1001" and zf='0' else
-- jne/jnz
'1' when
instruction(11 downto 8) = "0010" and zf='0' and cf='0' else --
ja
'1' when
instruction(11 downto 8) = "1011" and zf='0' and cf='1' else --
jb
'0';
---------------------------------------------------------------------
------------------
-- RAM interface -- RAM interface -- RAM interface --
RAM interface -- RAM interface --
---------------------------------------------------------------------
------------------
-- ram address to read instruction and read or write data
ram_address <= ip when fetch='1' else
reg2out(N-1 downto 0) when
instruction(15 downto 10)="000001" else
instruction(N-1 downto 0) when
instruction(15 downto 10)="000101" else
91. reg1out(N-1 downto 0) when
instruction(15 downto 10)="000010" else
reg1out(N-1 downto 0) when
instruction(15 downto 10)="000110" else
(others=>'0');
--"00000";
-- Enable write
ram_we <= '1' when execute='1' and instruction(15
downto 13)="000" and instruction(11 downto 10)="10" else
'0';
-- Data to write
ram_datawr <= wrdata;
---------------------------------------------------------------------
---------------------
-- External interface -- External interface -- External
interface -- External interface --
---------------------------------------------------------------------
---------------------
92. -- Instantiate a register to hold the output interface data
comp_regextout : entity work.dffre generic map (N=>8)
port
map(clk=>clk,rst=>rst,en=>ext_wren,d=>source,q=>ext_out);
ext_wren <= '1' when execute='1' and instruction(15
downto 13) = "110" and instruction(11 downto 10)="00" else
'0';
---------------------------------------------------------------------
-----------------
-- Write data -- Write data -- Write data -- Write data --
Write data -- Write data --
---------------------------------------------------------------------
-----------------
-- Data may be written to ram or memory. The enable
signals in the ram and register instances
-- control whether the write occurs.
-- Here we define what to write.
wrdata <= source when instruction(15 downto 13) = "000"
and instruction(11 downto 10)="00" else -- Move with
93. register or immediate as source
source when instruction(15 downto
13) = "000" and instruction(11 downto 10)="10" else
-- Move with register or immediate as source
ram_datard when instruction(15
downto 13) = "000" and instruction(11 downto 10)="01" else
-- Move with memory as source
aluqout when instruction(15 downto
13) = "001" else -- ALU
aluqout when instruction(15 downto
13) = "010" else -- ALU
aluqout when instruction(15 downto
13) = "011" else -- ALU
ext_in when instruction(15 downto 13)
= "110" and instruction(11 downto 10)="01" else --
Instruction in: read external input
"00000000";
-- Only for debugging
dbg_instr <= instruction;
dbg_seq <= seq;
dbg_flags <= flags;
94. end Behavioral;
labcpu/cpualu.vhd
-- ALU
-- The ALU uses 1 or 2 operands
-- The opcode are bits 14,13,12,11,10 of the instruction
-- a: input A of ALU
-- b: input B of ALU (not used for single operand instructions)
-- q: result (except for compare which is not used)
-- f: flag vectors with zero flag, overflow flag, carry flag and
sign flag.
95. library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity cpualu is
port (
clk : in STD_LOGIC;
rst : in STD_LOGIC;
op : in STD_LOGIC_VECTOR(4 downto 0);
a : in STD_LOGIC_VECTOR(7 downto 0);
b : in STD_LOGIC_VECTOR(7 downto 0);
q : out STD_LOGIC_VECTOR(7 downto 0);
f : out STD_LOGIC_VECTOR(3 downto 0)
);
end cpualu;
architecture Behavioral of cpualu is
96. signal sub : STD_LOGIC_VECTOR(8 downto 0); -- Do
subtraction on 9 bits to obtain the carry
signal r: STD_LOGIC_VECTOR(7 downto 0); -- ALU
result
signal zf,ovf,cf,sf : STD_LOGIC;
begin
--comp_rng: entity work.rng port map(clk=>clk,rst=>rst
sub <= ('0'&a) - ('0'&b);
r <= a+b when op(4 downto 3)="01" and op(1 downto
0)="00" else
sub(7 downto 0) when op(4 downto 3)="01"
and op(1 downto 0)="01" else
a and b when op(4 downto 3)="01" and
op(1 downto 0)="10" else
a or b when op(4 downto 3)="01" and op(1
downto 0)="11" else
a xor b when op(4 downto 3)="10" and
97. op(1 downto 0)="00" else
not a when op(4 downto 0)="11000" else
'0'&a(7 downto 1) when op(4 downto
0)="11001" else
a(0)&a(7 downto 1) when op(4 downto
0)="11010" else
a(7)&a(7 downto 1) when op(4 downto
0)="11011" else
a(6 downto 0)&a(7) when op(4 downto
0)="11100" else
"00000000";
sf <= sub(7);
zf <= not(sub(7) or sub(6) or sub(5) or sub(4) or sub(3) or
sub(2) or sub(1) or sub(0));
cf <= sub(8);
ovf <= (not a(7) and b(7) and sub(7)) or (a(7) and not b(7)
and not sub(7));
f<=zf&ovf&cf&sf;
q<=r;
98. end Behavioral;
labcpu/cpuregbank.vhd
-- CPU register banks holding the 4 CPU registers.
-- This is used to simplify the reading and writing to registers
-- by allowing to address them with a 2-bit address and enable
signal.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity cpuregbank is
port(
clk : in STD_LOGIC;
rrd1 : in STD_LOGIC_VECTOR(1 downto 0);
rrd2 : in STD_LOGIC_VECTOR(1 downto 0);
rwr : in STD_LOGIC_VECTOR(1 downto 0);
99. rwren : in STD_LOGIC;
rst : in STD_LOGIC;
d : in STD_LOGIC_VECTOR(7 downto 0);
q1 : out STD_LOGIC_VECTOR(7 downto 0);
q2 : out STD_LOGIC_VECTOR(7 downto 0);
-- Only for debugging
dbg_qa : out STD_LOGIC_VECTOR(7 downto 0);
dbg_qb : out STD_LOGIC_VECTOR(7 downto 0);
dbg_qc : out STD_LOGIC_VECTOR(7 downto 0);
dbg_qd : out STD_LOGIC_VECTOR(7 downto 0)
);
end cpuregbank;
architecture Behavioral of cpuregbank is
signal enables: STD_LOGIC_VECTOR(3 downto 0);
signal qa,qb,qc,qd: STD_LOGIC_VECTOR(7 downto 0);
begin
100. ra: entity work.dffre generic map (N=>8) port
map(clk=>clk,en=>enables(0),rst=>rst,d=>d,q=>qa);
rb: entity work.dffre generic map (N=>8) port
map(clk=>clk,en=>enables(1),rst=>rst,d=>d,q=>qb);
rc: entity work.dffre generic map (N=>8) port
map(clk=>clk,en=>enables(2),rst=>rst,d=>d,q=>qc);
rd: entity work.dffre generic map (N=>8) port
map(clk=>clk,en=>enables(3),rst=>rst,d=>d,q=>qd);
with rwr select
enables <= "0001" and
rwren&rwren&rwren&rwren when "00",
"0010" and
rwren&rwren&rwren&rwren when "01",
"0100" and
rwren&rwren&rwren&rwren when "10",
"1000" and
rwren&rwren&rwren&rwren when others;
with rrd1 select
q1 <= qa when "00",
101. qb when "01",
qc when "10",
qd when others;
with rrd2 select
q2 <= qa when "00",
qb when "01",
qc when "10",
qd when others;
-- Only for debugging
dbg_qa <= qa;
dbg_qb <= qb;
dbg_qc <= qc;
dbg_qd <= qd;
end Behavioral;
102. labcpu/cpusequencer.vhd
-- Generates the CPU state sequence seq: ld1 (00), ld2 (01),
exec (10)
-- Implementation with a D FF with synchronous reset and
enable
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity cpusequencer is
port(
clk : in STD_LOGIC;
rst : in STD_LOGIC;
en : in STD_LOGIC;
seq : out STD_LOGIC_VECTOR(1 downto 0)
);
end cpusequencer;
103. architecture Behavioral of cpusequencer is
signal s : STD_LOGIC_VECTOR(1 downto 0);
begin
process(clk,rst)
begin
if rising_edge(clk) then
if rst='1' then
s<="00";
else
if en='1' then
if s="10" then
s <= "00";
else
s <= s+1;
end if;
end if;
end if;
104. end if;
end process;
seq <= s;
end Behavioral;
labcpu/debounce.vhd
---------------------------------------------------------------------------
-----
--
-- FileName: debounce.vhd
-- Dependencies: none
-- Design Software: Quartus II 32-bit Version 11.1 Build 173
SJ Full Version
--
-- HDL CODE IS PROVIDED "AS IS." DIGI-KEY
EXPRESSLY DISCLAIMS ANY
-- WARRANTY OF ANY KIND, WHETHER EXPRESS OR
105. IMPLIED, INCLUDING BUT NOT
-- LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A
-- PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN
NO EVENT SHALL DIGI-KEY
-- BE LIABLE FOR ANY INCIDENTAL, SPECIAL,
INDIRECT OR CONSEQUENTIAL
-- DAMAGES, LOST PROFITS OR LOST DATA, HARM TO
YOUR EQUIPMENT, COST OF
-- PROCUREMENT OF SUBSTITUTE GOODS,
TECHNOLOGY OR SERVICES, ANY CLAIMS
-- BY THIRD PARTIES (INCLUDING BUT NOT LIMITED
TO ANY DEFENSE THEREOF),
-- ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION,
OR OTHER SIMILAR COSTS.
--
-- Version History
-- Version 1.0 3/26/2012 Scott Larson
-- Initial Public Release
--
---------------------------------------------------------------------------
-----
106. LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
ENTITY debounce IS
GENERIC(
counter_size : INTEGER := 19); --counter size (19 bits
gives 10.5ms with 50MHz clock)
PORT(
clk : IN STD_LOGIC; --input clock
button : IN STD_LOGIC; --input signal to be debounced
result : OUT STD_LOGIC); --debounced signal
END debounce;
ARCHITECTURE logic OF debounce IS
SIGNAL flipflops : STD_LOGIC_VECTOR(1 DOWNTO 0);
--input flip flops
SIGNAL counter_set : STD_LOGIC; --sync reset
to zero
107. SIGNAL counter_out : STD_LOGIC_VECTOR(counter_size
DOWNTO 0) := (OTHERS => '0'); --counter output
BEGIN
counter_set <= flipflops(0) xor flipflops(1); --determine
when to start/reset counter
PROCESS(clk)
BEGIN
IF(clk'EVENT and clk = '1') THEN
flipflops(0) <= button;
flipflops(1) <= flipflops(0);
If(counter_set = '1') THEN --reset counter
because input is changing
counter_out <= (OTHERS => '0');
ELSIF(counter_out(counter_size) = '0') THEN --stable input
time is not yet met
counter_out <= counter_out + 1;
ELSE --stable input time is met
result <= flipflops(1);
108. END IF;
END IF;
END PROCESS;
END logic;
labcpu/dffre.vhd
-- 8-bit register (D flip-flop) with synchronous enable and reset
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity dffre is
generic (N : integer);
port(
clk : in STD_LOGIC;
en : in STD_LOGIC;
rst: in STD_LOGIC;
109. d : in STD_LOGIC_VECTOR(N-1 downto 0);
q : out STD_LOGIC_VECTOR(N-1 downto 0)
);
end dffre;
architecture Behavioral of dffre is
begin
process(clk)
begin
if rising_edge(clk) then
if rst='1' then
q<=(others=>'0');
else
if en='1' then
q<=d;
end if;
end if;
110. end if;
end process;
end Behavioral;
labcpu/edgedetect.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity edgedetect is
port(
clk : in STD_LOGIC;
din : in STD_LOGIC;
dout : out STD_LOGIC
);
111. end edgedetect;
architecture Behavioral of edgedetect is
signal last : STD_LOGIC;
begin
process(clk)
begin
if rising_edge(clk) then
last <= din;
end if;
end process;
dout <= din and not last;
end Behavioral;
112. labcpu/hexto7seg.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use IEEE.std_logic_unsigned.ALL;
entity hexto7seg is
port(
clk: in std_logic;
d7: in std_logic_vector(3 downto 0);
d6: in std_logic_vector(3 downto 0);
d5: in std_logic_vector(3 downto 0);
d4: in std_logic_vector(3 downto 0);
d3: in std_logic_vector(3 downto 0);
d2: in std_logic_vector(3 downto 0);
d1: in std_logic_vector(3 downto 0);
d0: in std_logic_vector(3 downto 0);
blink: in std_logic_vector(7 downto 0);
q: out std_logic_vector(6 downto 0);
active : out std_logic_vector(7 downto 0)
113. );
end hexto7seg;
architecture Behavioral of hexto7seg is
signal a: std_logic;
signal b: std_logic;
signal c: std_logic;
signal d: std_logic;
signal qt: std_logic_vector(6 downto 0);
signal ctr: std_logic_vector(2 downto 0);
signal divider: std_logic_vector(25 downto 0);
begin
p1: process(clk)
begin
if rising_edge(clk) then
divider<=divider+1;
114. end if;
end process;
p2: process(clk)
begin
if rising_edge(clk) then
if divider(9 downto 0)="0000000000"
then
ctr<=ctr+1;
end if;
end if;
end process;
-- input mux
with ctr select
a <= d0(3) when "000",
d1(3) when "001",
d2(3) when "010",
d3(3) when "011",
d4(3) when "100",
d5(3) when "101",
115. d6(3) when "110",
d7(3) when others;
with ctr select
b <= d0(2) when "000",
d1(2) when "001",
d2(2) when "010",
d3(2) when "011",
d4(2) when "100",
d5(2) when "101",
d6(2) when "110",
d7(2) when others;
with ctr select
c <= d0(1) when "000",
d1(1) when "001",
d2(1) when "010",
d3(1) when "011",
d4(1) when "100",
d5(1) when "101",
116. d6(1) when "110",
d7(1) when others;
with ctr select
d <= d0(0) when "000",
d1(0) when "001",
d2(0) when "010",
d3(0) when "011",
d4(0) when "100",
d5(0) when "101",
d6(0) when "110",
d7(0) when others;
-- Output mux
with ctr select
active <= "11111110" when "000",
"11111101" when "001",
"11111011" when "010",
"11110111" when "011",
117. "11101111" when "100",
"11011111" when "101",
"10111111" when "110",
"01111111" when others;
-- Blinking
q(0) <= (blink(to_integer(unsigned(ctr))) and divider(25))
or qt(0);
q(1) <= (blink(to_integer(unsigned(ctr))) and divider(25))
or qt(1);
q(2) <= (blink(to_integer(unsigned(ctr))) and divider(25))
or qt(2);
q(3) <= (blink(to_integer(unsigned(ctr))) and divider(25))
or qt(3);
q(4) <= (blink(to_integer(unsigned(ctr))) and divider(25))
or qt(4);
q(5) <= (blink(to_integer(unsigned(ctr))) and divider(25))
or qt(5);
q(6) <= (blink(to_integer(unsigned(ctr))) and divider(25))
or qt(6);
118. qt(0) <= not ( (not a and not b and not c and not d )
or (not a and not b and c and not d)
or (not a and not b and c and d)
or (not a and b and not c and d)
or (not a and b and c and not d)
or (not a and b and c and d)
or (a and not b and not c and not d)
or (a and not b and not c and d)
or (a and not b and c and not d)
or (a and b and not c and not d)
or (a and b and c and not d)
or (a and b and c and d) );
qt(1) <= not ( (not a and not b and not c and not d)
or (not a and not b and not c and d)
or (not a and not b and c and not d)
or (not a and not b and c and c)
119. or (not a and b and not c and not d)
or (not a and b and c and d)
or (a and not b and not c and not d)
or (a and not b and not c and d)
or (a and not b and c and not d)
or (a and b and not c and d) );
qt(2) <= not ( (not a and not b and not c and not d)
or (not a and not b and not c and d)
or (not a and not b and c and d)
or (not a and b and not c and not d)
or (not a and b and not c and d)
or (not a and b and c and not d)
or (not a and b and c and d)
or (a and not b and not c and not d)
or (a and not b and not c and d)
or (a and not b and c and not d)
or (a and not b and c and d)
120. or (a and b and not c and d) );
qt(3) <= not ((not a and not b and not c and not d)
or (not a and not b and c and not d)
or (not a and not b and c and d)
or (not a and b and not c and d)
or (not a and b and c and not d)
or (a and not b and not c and not d)
or (a and not b and c and d)
or (a and b and not c and not d)
or (a and b and not c and d)
or (a and b and c and not d) );
--qt(4) <= not ((not a and not b and not c and not d)
-- or (not a and not b and c and not d)
-- or (not a and b and c and not d)
-- or (a and not b and not c and not d)
-- or (a and not b and c and not d)
-- or (a and not b and c and d)
121. -- or (a and b and not c and not d)
-- or (a and b and not c and d)
-- or (a and b and c and not d)
-- or (a and b and c and d) );
--qt(5) <= not ((not a and not b and not c and not d)
-- or (not a and b and not c and not d)
-- or (not a and b and not c and d)
-- or (not a and b and c and not d)
-- or (a and not b and not c and not d)
-- or (a and not b and not c and d)
-- or (a and not b and c and not d)
-- or (a and not b and c and d)
-- or (a and b and not c and not d)
-- or (a and b and c and not d)
-- or (a and b and c and d) );
122. --qt(6) <= not ((not a and not b and c and not d)
-- or (not a and not b and c and d)
-- or (not a and b and not c and not d)
-- or (not a and b and not c and d)
-- or (not a and b and c and not d)
-- or (a and not b and not c and not d)
-- or (a and not b and not c and d)
-- or (a and not b and c and not d)
-- or (a and not b and c and d)
-- or (a and b and not c and d)
-- or (a and b and c and not d)
-- or (a and b and c and d) );
-- Minimized expression:
qt(4) <= not( (a and b) or (a and c) or (c and not d) or (not
b and not d) );
qt(5) <= not( (b and not d) or (not a and b and not c) or (a
and not b) or (a and c) or (not c and not d) );
123. qt(6) <= not( (not a and b and not c) or (a and not b) or (a
and d) or (not b and c and d) or (c and not d) );
end Behavioral;
labcpu/labcpu.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity main is
Port (
clk : in STD_LOGIC;
btnU : in STD_LOGIC;
btnD : in STD_LOGIC;
btnL : in STD_LOGIC;
btnC : in STD_LOGIC;
124. btnR : in STD_LOGIC;
btnCpuReset : in STD_LOGIC;
sw : in STD_LOGIC_VECTOR (15
downto 0);
led : out STD_LOGIC_VECTOR (15
downto 0);
seg : out STD_LOGIC_VECTOR(6 downto
0);
an : out STD_LOGIC_VECTOR(7 downto
0)
);
end main;
architecture Structural of main is
signal reset : STD_LOGIC;
-- clocks
signal clkmain : STD_LOGIC;
signal clkslow : STD_LOGIC;
125. signal cpu_ram_we : STD_LOGIC;
signal cpu_ram_address : STD_LOGIC_VECTOR(4
downto 0);
signal cpu_ram_datawr : STD_LOGIC_VECTOR(7 downto
0);
signal cpu_ram_datard : STD_LOGIC_VECTOR(7 downto
0);
signal ramedit_address : STD_LOGIC_VECTOR(4 downto
0);
signal ramedit_data : STD_LOGIC_VECTOR(7 downto 0);
signal ramedit_enable : STD_LOGIC;
signal ramedit_we : STD_LOGIC;
-- Display signals
126. signal display_d7 : STD_LOGIC_VECTOR(3 downto 0);
signal display_d6 : STD_LOGIC_VECTOR(3 downto 0);
signal display_d5 : STD_LOGIC_VECTOR(3 downto 0);
signal display_d4 : STD_LOGIC_VECTOR(3 downto 0);
signal display_d3 : STD_LOGIC_VECTOR(3 downto 0);
signal display_d2 : STD_LOGIC_VECTOR(3 downto 0);
signal display_d1 : STD_LOGIC_VECTOR(3 downto 0);
signal display_d0 : STD_LOGIC_VECTOR(3 downto 0);
signal display_blink : STD_LOGIC_VECTOR(7 downto
0);
signal cpu_d0, cpu_d1, cpu_d2, cpu_d3, cpu_d4, cpu_d5,
cpu_d6, cpu_d7 : STD_LOGIC_VECTOR(3 downto 0);
-- RAM signals
signal ramclk : STD_LOGIC;
signal ram_address : STD_LOGIC_VECTOR(4 downto 0);
signal ram_datain : STD_LOGIC_VECTOR(7 downto 0);
signal ram_we : STD_LOGIC;
signal ram_dataout : STD_LOGIC_VECTOR(7 downto 0);
127. -- debouncing
signal btnUd,btnDd,btnLd,btnCd,btnRd,btnCpuResetd :
STD_LOGIC;
signal sw15d,sw13d : STD_LOGIC;
-- edge detect
signal btnUde,btnDde,btnLde,btnRde : STD_LOGIC;
-- Only for CPU debugging
signal dbg_qa : STD_LOGIC_VECTOR(7 downto 0);
signal dbg_qb : STD_LOGIC_VECTOR(7 downto 0);
signal dbg_qc : STD_LOGIC_VECTOR(7 downto 0);
signal dbg_qd : STD_LOGIC_VECTOR(7 downto 0);
signal dbg_instr : STD_LOGIC_VECTOR(15 downto 0);
signal dbg_seq : STD_LOGIC_VECTOR(1 downto 0);
signal dbg_flags : STD_LOGIC_VECTOR(3 downto 0);
begin
-- Debouncing
128. comp_deb1 : entity work.debounce port
map(clk=>clk,button=>btnC,result=>btnCd);
comp_deb2 : entity work.debounce port
map(clk=>clk,button=>btnU,result=>btnUd);
comp_deb3 : entity work.debounce port
map(clk=>clk,button=>btnD,result=>btnDd);
comp_deb4 : entity work.debounce port
map(clk=>clk,button=>btnL,result=>btnLd);
comp_deb5 : entity work.debounce port
map(clk=>clk,button=>btnR,result=>btnRd);
comp_deb6 : entity work.debounce port
map(clk=>clk,button=>btnCpuReset,result=>btnCpuResetd);
comp_deb7 : entity work.debounce port
map(clk=>clk,button=>sw(15),result=>sw15d);
comp_deb8 : entity work.debounce port
map(clk=>clk,button=>sw(13),result=>sw13d);
-- Edge detectors on some buttons (for RAM editor)
comp_edg1 : entity work.edgedetect port
map(clk=>clk,din=>btnLd,dout=>btnLde);
comp_edg2 : entity work.edgedetect port
map(clk=>clk,din=>btnRd,dout=>btnRde);
comp_edg3 : entity work.edgedetect port
129. map(clk=>clk,din=>btnUd,dout=>btnUde);
comp_edg4 : entity work.edgedetect port
map(clk=>clk,din=>btnDd,dout=>btnDde);
-- slow clock
--
comp_clk : entity work.clkdiv generic map(N=>25) port
map(clkin=>clk,clkout=>clkslow);
-- Reset
--
reset <= not btnCpuResetd;
-- Toggle the RAM edit mode according to sw15d
--
ramedit_enable <= sw15d;
-- Display debug status on LEDs
130. --
led(15) <= ramedit_enable;
led(14) <= clkmain;
led(13 downto 12) <= dbg_seq;
led(11 downto 8) <= dbg_flags;
-- Display multiplexers: toggle between ram edit and cpu
mode
display_blink <=
"00"&ramedit_enable&ramedit_enable&ramedit_enable&ramedi
t_enable&ramedit_enable&ramedit_enable;
display_d7 <= "0000" when ramedit_enable='1' else
cpu_d7;
display_d6 <= "0000" when ramedit_enable='1' else
cpu_d6;
display_d5 <= "000"&ram_address(4 downto 4) when
ramedit_enable='1' else cpu_d5;
display_d4 <= ram_address(3 downto 0) when
ramedit_enable='1' else cpu_d4;
display_d3 <= sw(7 downto 4) when ramedit_enable='1'
else cpu_d3;
133. active=>an);
--comp2: entity work.clkdiv generic map (N => 26) port
map( clkin=>clk,clkout=>clkmain );
--led(15)<=clkmain;
clkmain <= not ramedit_enable and( (btnCd and not
sw13d) or (clkslow and sw13d));
-- Instantiate RAM
-- RAM clock is either board clock in edit mode, or manual
clock
ramclk <= clk when sw15d='1' else clkmain;
comp3: entity work.ram generic map(N=>5) port
map(clk=>ramclk,address=>ram_address,data=>ram_datain,we=
>ram_we,q=>ram_dataout);
-- Instantiate the RAM editor
134. comp_ramedit:
entity work.ramedit generic map(N=>5) port
map(clk=>clk,rst=>reset,btnU=>btnUde,btnD=>btnDde,btnL=>
btnLde,btnR=>btnRde,din=>sw,
we=>ramedit_we,address=>ramedit_address,data=>ramedit
_data);
-- Multiplex the editor and the CPU to the RAM
--
ram_we <= ramedit_we when ramedit_enable='1' else
cpu_ram_we;
ram_address <= ramedit_address when ramedit_enable='1'
else cpu_ram_address;
ram_datain <= ramedit_data when ramedit_enable='1' else
cpu_ram_datawr;
-- Instantiate the CPU
comp_cpu:
135. entity work.CPU generic map(N=>5)
port
map(clk=>clkmain,rst=>reset,ext_in=>sw(7 downto
0),ext_out=>led(7 downto 0),
ram_we=>cpu_ram_we,ram_address=>cpu_ram_address,ra
m_datawr=>cpu_ram_datawr,ram_datard=>ram_dataout,
dbg_qa=>dbg_qa,dbg_qb=>dbg_qb,dbg_qc=>dbg_qc,dbg_
qd=>dbg_qd,
dbg_instr=>dbg_instr,dbg_seq=>dbg_seq,dbg_flags=>dbg_
flags);
end Structural;
labcpu/Nexys4_Master.xdc
## This file is a general .xdc for the Nexys4 rev B board
## To use it in a project:
## - uncomment the lines corresponding to used pins
## - rename the used ports (in each line, after get_ports)
136. according to the top level signal names in the project
## Clock signal
##Bank = 35, Pin name = IO_L12P_T1_MRCC_35,
Sch name = CLK100MHZ
set_property PACKAGE_PIN E3 [get_ports clk]
set_property IOSTANDARD LVCMOS33 [get_ports clk]
create_clock -add -name sys_clk_pin -period 10.00 -
waveform {0 5} [get_ports clk]
## Switches
#Bank = 34, Pin name = IO_L21P_T3_DQS_34,
Sch name = SW0
set_property PACKAGE_PIN U9 [get_ports {sw[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports
{sw[0]}]
#Bank = 34, Pin name = IO_25_34,
Sch name = SW1
set_property PACKAGE_PIN U8 [get_ports {sw[1]}]