Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
S
simuDAtor
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Computer Engineering
simuDAtor
Commits
8eeffdd6
Commit
8eeffdd6
authored
10 months ago
by
Johannes Kung
Browse files
Options
Downloads
Patches
Plain Diff
Corrected faulty MIA LC behaviour
parent
5dfed841
No related branches found
No related tags found
1 merge request
!44
Fixed flags
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
src/simudator/processor/mia/modules/lc.py
+75
-125
75 additions, 125 deletions
src/simudator/processor/mia/modules/lc.py
test/test_mia/test_lc.py
+81
-45
81 additions, 45 deletions
test/test_mia/test_lc.py
with
156 additions
and
170 deletions
src/simudator/processor/mia/modules/lc.py
+
75
−
125
View file @
8eeffdd6
...
...
@@ -10,17 +10,43 @@ class LC(Module):
"""
A class representing the loop counter. It is controlled by the
signal uM_control which determines if it should read from bus,
increase by one or read from mM_uADR.
Parameters
----------
mM_control : Signal
A signal connection from the micro memory
to the loop counter. This allows the micro memory to send bit
12 and 13 to the loop counter. Bit 12 and 13 decides the
loop counters behaviour.
bus_input : Signal
A signal connection from the bus to the loop
counter. The loop counter reads from this signal when it reads
from the bus.
l_flag : Signal
A signal connection from the loop counter to the
L-flag. The loop counter writes to this signal when it needs to
update the L-flag.
mM_uADR : Signal
A signal connection from the micro memory to
the loop counter. This allows the loop counter to read the 7
least significant bits from the uADR field.
name : str
Optional name of the loop counter.
value : int
Optional start value of the loop counter.
"""
__slots__
=
(
"
value
"
,
"
read_from_bus
"
,
"
read_from_uADR
"
,
"
decrement_by_one
"
,
"
bit_length
"
,
"
mask
"
,
"
_value
"
,
"
_set_l_flag
"
,
)
BIT_LENGTH
=
8
"""
Number of bits used to store the loop counter value. Used to truncate too
large input.
"""
def
__init__
(
self
,
mM_control
:
Signal
,
...
...
@@ -29,35 +55,7 @@ class LC(Module):
mM_uADR
:
Signal
,
name
=
"
LC
"
,
value
=
0
,
bit_length
=
8
,
)
->
None
:
"""
Parameters
----------
mM_control : Signal
A signal connection from the micro memory
to the loop counter. This allows the micro memory to send bit
12 and 13 to the loop counter. Bit 12 and 13 decides the
loop counters behaviour.
bus_input : Signal
A signal connection from the bus to the loop
counter. The loop counter reads from this signal when it reads
from the bus.
l_flag : Signal
A signal connection from the loop counter to the
L flag. The loop counter writes to this signal when it needs to
update the L flag.
mM_uADR : Signal
A signal connection from the micro memory to
the loop counter. This allows the loop counter to read the 7
least significant bits from the uADR field.
name : str
Optional name of the loop counter.
value : int
Optional start value of the loop counter.
bit_length : int
Optional bit length of the loop counter.
"""
# signals
signals
=
{
...
...
@@ -70,127 +68,85 @@ class LC(Module):
super
().
__init__
(
signals
,
name
)
# the value of the loop counter
self
.
value
=
value
self
.
_
value
=
value
# helper variables
self
.
read_from_bus
=
False
self
.
read_from_uADR
=
False
self
.
decrement_by_one
=
False
# bit length and mask
self
.
bit_length
=
bit_length
self
.
mask
=
2
**
self
.
bit_length
-
1
# helper to correctly set and reset the L-flag
self
.
_set_l_flag
=
False
def
update_register
(
self
)
->
None
:
"""
Reads bit 12 and 13 from the micro memory and updates the
loop counter.
0 - does nothing.
1 - decrements the loop counter by one.
2 - loads the 8 least significant bits from the bus.
3 - loads the 7 least significant bits from the uADR field.
"""
Read bit 12 and 13 from the micro memory and update the
loop counter accordingly.
0 - do nothing.
1 - decrement the loop counter by one.
2 - load the 8 least significant bits from the bus.
3 - load the 7 least significant bits from the uADR field.
"""
bit_mask
=
2
**
LC
.
BIT_LENGTH
-
1
match
self
.
signals
[
"
in_control
"
].
get_value
():
case
0b00
:
# LC is not effected
self
.
decrement_by_one
=
False
self
.
read_from_bus
=
False
self
.
read_from_uADR
=
False
case
0b00
:
# Do nothing
return
case
0b01
:
# Decrement by one
self
.
decrement_by_one
=
True
self
.
read_from_bus
=
False
self
.
read_from_uADR
=
False
case
0b10
:
# Load 8 least significant bits from bus
self
.
decrement_by_one
=
False
self
.
read_from_bus
=
True
self
.
read_from_uADR
=
False
case
0b11
:
# LCs 7 least significant bits are loaded from uADR
self
.
decrement_by_one
=
False
self
.
read_from_bus
=
False
self
.
read_from_uADR
=
True
self
.
_value
-=
1
if
self
.
read_from_bus
:
input_value
=
self
.
signals
[
"
in_input
"
].
get_value
()
self
.
value
=
input_value
&
self
.
mask
if
self
.
_value
<
0
:
# underflow correctly
# (the bit mask is the same as the maximum value)
self
.
_value
=
bit_mask
if
self
.
read_from_uADR
:
input_value
=
self
.
signals
[
"
in_address
"
].
get_value
()
self
.
value
=
input_value
&
self
.
mask
case
0b10
:
# Load 8 least significant bits from bus
self
.
_value
=
self
.
signals
[
"
in_input
"
].
get_value
()
if
self
.
decrement_by_one
:
self
.
value
-
=
1
case
0b11
:
# Load 7 least significant bits from uADR
self
.
_
value
=
self
.
signals
[
"
in_address
"
].
get_value
()
# overflow correctly
if
self
.
value
<
0
:
self
.
value
=
self
.
mask
# Truncate if the value is too large and determine if the L-flag
# should be set
self
.
_value
=
self
.
_value
&
bit_mask
self
.
_set_l_flag
=
self
.
_value
==
0
def
output_register
(
self
)
->
None
:
"""
The loop counter will only output to the L flag, this is
handled in
'
update_logic
'
.
"""
pass
def
update_logic
(
self
)
->
None
:
"""
When the loop counter reaches zero, set the l flag to 1.
Otherwise set it to zero.
"""
Set the L-flag to 1 if the loop counter has reached zero. Set the
L-flag to 0 if the loop counter is not zero.
"""
if
self
.
value
==
0
:
if
self
.
_set_l_flag
:
self
.
signals
[
"
out_flag_l
"
].
update_value
(
1
)
else
:
self
.
signals
[
"
out_flag_l
"
].
update_value
(
0
)
def
get_state
(
self
)
->
dict
[
str
,
Any
]:
"""
Returns a dict of the loop counter state.
These states are changable via set_states.
def
update_logic
(
self
)
->
None
:
"""
Do nothing.
Returns
-------
dict[Any]
The state of the loop counter.
The loop counter has no internal logic.
"""
pass
def
get_state
(
self
)
->
dict
[
str
,
Any
]:
state
=
dict
()
state
[
"
name
"
]
=
self
.
name
state
[
"
value
"
]
=
self
.
value
state
[
"
bit_length
"
]
=
self
.
bit_length
state
[
"
mask
"
]
=
self
.
mask
state
[
"
read_from_bus
"
]
=
self
.
read_from_bus
state
[
"
read_from_uADR
"
]
=
self
.
read_from_uADR
state
[
"
decrement_by_one
"
]
=
self
.
decrement_by_one
state
[
"
value
"
]
=
self
.
_value
state
[
"
bit_length
"
]
=
LC
.
BIT_LENGTH
return
state
def
set_state
(
self
,
state
:
dict
[
str
,
Any
])
->
None
:
"""
Sets the loop counter state to one given in dict.
"""
self
.
name
=
state
[
"
name
"
]
self
.
value
=
state
[
"
value
"
]
if
"
bit_length
"
in
state
:
self
.
bit_length
=
state
[
"
bit_length
"
]
if
"
mask
"
in
state
:
self
.
mask
=
state
[
"
mask
"
]
if
"
read_from_bus
"
in
state
:
self
.
read_from_bus
=
state
[
"
read_from_bus
"
]
if
"
read_from_uADR
"
in
state
:
self
.
read_from_uADR
=
state
[
"
read_from_uADR
"
]
if
"
decrement_by_one
"
in
state
:
self
.
decrement_by_one
=
state
[
"
decrement_by_one
"
]
self
.
_value
=
state
[
"
value
"
]
def
reset
(
self
)
->
None
:
"""
Resets the loop counter to 0.
"""
self
.
value
=
0
self
.
read_from_bus
=
False
self
.
read_from_uADR
=
False
self
.
decrement_by_one
=
False
"""
Reset the loop counter to 0.
"""
self
.
_value
=
0
def
save_state_to_file
(
self
,
file_path
:
str
)
->
bool
:
content
=
self
.
name
+
"
:
\n
"
content
+=
"
value:
"
+
hex
(
self
.
value
)[
2
:]
+
"
\n\n
"
content
+=
"
value:
"
+
hex
(
self
.
_
value
)[
2
:]
+
"
\n\n
"
return
super
().
_helper_save_state_to_file
(
file_path
,
content
)
def
load_from_str
(
self
,
state_string
):
string_pair
=
state_string
.
split
(
"
:
"
)
# TODO: Maybe check if it starts with value: ?
self
.
value
=
int
(
string_pair
[
1
],
16
)
self
.
_
value
=
int
(
string_pair
[
1
],
16
)
def
print_module
(
self
)
->
None
:
print
(
...
...
@@ -198,11 +154,5 @@ class LC(Module):
self
.
name
,
"
\n
-----
"
,
"
\n
value:
"
,
hex
(
self
.
value
),
"
\n
decrement:
"
,
self
.
decrement_by_one
,
"
\n
read from uADR:
"
,
self
.
read_from_uADR
,
"
\n
read from bus:
"
,
self
.
read_from_bus
,
hex
(
self
.
_value
),
)
This diff is collapsed.
Click to expand it.
test/test_mia/test_lc.py
+
81
−
45
View file @
8eeffdd6
from
simudator.core.modules.integer_register
import
IntegerRegister
from
simudator.core.processor
import
Processor
from
simudator.core.signal
import
Signal
from
simudator.processor.mia.modules.lc
import
LC
...
...
@@ -28,11 +27,37 @@ def test_read_from_bus():
cpu
.
add_module
(
lc
)
bus_input_s
.
update_value
(
10
)
# Set the LC to read from the bus
mM_control_s
.
update_value
(
2
)
# Reading a non-zero value should set the L-flag to 0
bus_input_s
.
update_value
(
10
)
cpu
.
do_tick
()
assert
lc
.
_value
==
10
assert
l_flag_s
.
get_value
()
==
0
# Reading a zero while having a non-zero value should set the L-flag to 1
bus_input_s
.
update_value
(
0
)
cpu
.
do_tick
()
assert
lc
.
_value
==
0
assert
l_flag_s
.
get_value
()
==
1
# Reading a zero again should not reset the L-flag
cpu
.
do_tick
()
assert
lc
.
value
==
10
assert
lc
.
_value
==
0
assert
l_flag_s
.
get_value
()
==
1
# Reading a non-zero value now should reset the L-flag
bus_input_s
.
update_value
(
2
)
cpu
.
do_tick
()
assert
lc
.
_value
==
2
assert
l_flag_s
.
get_value
()
==
0
# Check that the inputted value is correctly truncated
bus_input_s
.
update_value
(
0xFF1A
)
cpu
.
do_tick
()
assert
lc
.
_value
==
0x1A
assert
l_flag_s
.
get_value
()
==
0
def
test_read_from_uADR
():
...
...
@@ -45,14 +70,40 @@ def test_read_from_uADR():
cpu
.
add_module
(
lc
)
# Set the LC to read from uADR
mM_control_s
.
update_value
(
0b11
)
# Reading a non-zero value should set the L-flag to 0
mM_uADR_s
.
update_value
(
10
)
mM_control_s
.
update_value
(
3
)
cpu
.
do_tick
()
assert
lc
.
_value
==
10
assert
l_flag_s
.
get_value
()
==
0
# Reading a zero while having a non-zero value should set the L-flag to 1
mM_uADR_s
.
update_value
(
0
)
cpu
.
do_tick
()
assert
lc
.
_value
==
0
assert
l_flag_s
.
get_value
()
==
1
# Reading a zero again should not reset the L-flag
cpu
.
do_tick
()
assert
lc
.
value
==
10
assert
lc
.
_value
==
0
assert
l_flag_s
.
get_value
()
==
1
# Reading a non-zero value now should reset the L-flag
mM_uADR_s
.
update_value
(
2
)
cpu
.
do_tick
()
assert
lc
.
_value
==
2
assert
l_flag_s
.
get_value
()
==
0
# Check that the inputted value is correctly truncated
mM_uADR_s
.
update_value
(
0xFF1A
)
cpu
.
do_tick
()
assert
lc
.
_value
==
0x1A
assert
l_flag_s
.
get_value
()
==
0
def
test_
write_to_l_flag
():
def
test_
decrement
():
cpu
=
Processor
()
# signals needed
...
...
@@ -63,7 +114,7 @@ def test_write_to_l_flag():
# modules needed to run the test
# initialize loop counter to 1, so when it is decremented by
# one it reaches zero and sets the L
flag
# one it reaches zero and sets the L
-
flag
lc_value
=
1
lc
=
LC
(
mM_control_s
,
bus_input_s
,
l_flag_s
,
mM_uADR_s
,
"
lc
"
,
lc_value
)
...
...
@@ -75,31 +126,15 @@ def test_write_to_l_flag():
mM_control_s
.
update_value
(
0b01
)
# The loop counter will now change its value from 1 to 0 which
# should set the L
flag to 1 in the same cycle
# should set the L
-
flag to 1 in the same cycle
cpu
.
do_tick
()
assert
lc
.
_value
==
0
assert
l_flag_s
.
get_value
()
==
1
def
test_reset_l_flag
():
cpu
=
Processor
()
mM_control_s
=
Signal
(
cpu
)
mM_uADR_s
=
Signal
(
cpu
)
l_flag_s
=
Signal
(
cpu
)
bus_input_s
=
Signal
(
cpu
)
lc
=
LC
(
mM_control_s
,
bus_input_s
,
l_flag_s
,
mM_uADR_s
,
"
lc
"
,
1
)
cpu
.
add_module
(
lc
)
mM_uADR_s
.
update_value
(
0
)
mM_control_s
.
update_value
(
3
)
cpu
.
do_tick
()
mM_uADR_s
.
update_value
(
10
)
# Decrementing again should make the LC wrap around to 0xFF and reset the
# L-flag
cpu
.
do_tick
()
assert
lc
.
_value
==
0xFF
assert
l_flag_s
.
get_value
()
==
0
...
...
@@ -119,13 +154,29 @@ def test_lc_do_nothing():
mM_control_s
.
update_value
(
0b01
)
cpu
.
do_tick
()
assert
lc
.
value
==
3
assert
lc
.
_value
==
3
assert
l_flag_s
.
get_value
()
==
0
# tell lc to do nothing
mM_control_s
.
update_value
(
0b00
)
cpu
.
do_tick
()
assert
lc
.
value
==
3
assert
lc
.
_value
==
3
assert
l_flag_s
.
get_value
()
==
0
# decrement to zero and then do nothing to check that the L-flag remains
# set to 1
mM_control_s
.
update_value
(
0b01
)
cpu
.
do_tick
()
cpu
.
do_tick
()
cpu
.
do_tick
()
assert
lc
.
_value
==
0
assert
l_flag_s
.
get_value
()
==
1
mM_control_s
.
update_value
(
0b00
)
cpu
.
do_tick
()
assert
lc
.
_value
==
0
assert
l_flag_s
.
get_value
()
==
1
def
test_get_state
():
...
...
@@ -147,11 +198,6 @@ def test_get_state():
state
=
lc
.
get_state
()
assert
state
[
"
name
"
]
==
"
LC
"
assert
state
[
"
value
"
]
==
255
assert
state
[
"
mask
"
]
==
255
assert
state
[
"
bit_length
"
]
==
8
assert
state
[
"
read_from_bus
"
]
is
False
assert
state
[
"
read_from_uADR
"
]
is
False
assert
state
[
"
decrement_by_one
"
]
is
True
mM_control_s
.
update_value
(
0b10
)
cpu
.
do_tick
()
...
...
@@ -159,11 +205,6 @@ def test_get_state():
state
=
lc
.
get_state
()
assert
state
[
"
name
"
]
==
"
LC
"
assert
state
[
"
value
"
]
==
100
assert
state
[
"
mask
"
]
==
255
assert
state
[
"
bit_length
"
]
==
8
assert
state
[
"
read_from_bus
"
]
is
True
assert
state
[
"
read_from_uADR
"
]
is
False
assert
state
[
"
decrement_by_one
"
]
is
False
mM_control_s
.
update_value
(
0b11
)
cpu
.
do_tick
()
...
...
@@ -171,8 +212,3 @@ def test_get_state():
state
=
lc
.
get_state
()
assert
state
[
"
name
"
]
==
"
LC
"
assert
state
[
"
value
"
]
==
10
assert
state
[
"
mask
"
]
==
255
assert
state
[
"
bit_length
"
]
==
8
assert
state
[
"
read_from_bus
"
]
is
False
assert
state
[
"
read_from_uADR
"
]
is
True
assert
state
[
"
decrement_by_one
"
]
is
False
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment