Skip to content

Commit 23d4ccb

Browse files
committed
Microcode constant support for Clojure
Cleaned up Ruby constants, too. The whole CONSTANT_N thing makes no sense.
1 parent 5127332 commit 23d4ccb

File tree

5 files changed

+31
-38
lines changed

5 files changed

+31
-38
lines changed

lib/Computer.Build.rb

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,6 @@ def generate
4242
m.signal :opcode,
4343
VHDL::STD_LOGIC_VECTOR((opcode_length-1)..0)
4444

45-
states.values.map(&:constant_value).compact.uniq.each do |const|
46-
m.constant "CONSTANT_#{const}", VHDL::STD_LOGIC_VECTOR(7..0), const.to_logic(8)
47-
end
48-
4945
m.reset do |r|
5046
r.goto :fetch
5147
control_signals.each do |sig|
@@ -63,7 +59,7 @@ def generate
6359
s.assign :alu_operation, state.alu_op ? state.alu_op.opcode : "000"
6460

6561
if state.constant_value
66-
s.assign :system_bus, "CONSTANT_#{state.constant_value}".to_sym
62+
s.assign :system_bus, state.constant_value.to_logic(8)
6763
else
6864
s.assign :system_bus, "ZZZZZZZZ"
6965
end

lib/computer_build/state_machine.rb

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ def initialize(name, body)
3636
@signals = []
3737
@states = []
3838
@transitions = []
39-
@constants = []
4039
body[self]
4140
end
4241

@@ -76,10 +75,6 @@ def transition(options)
7675
@transitions << Transition.new(options)
7776
end
7877

79-
def constant(*args)
80-
@constants << VHDL::Constant.new(*args)
81-
end
82-
8378
def generate(out)
8479
representation = entity(@name) do |e|
8580
e.port "clock", :in, VHDL::STD_LOGIC
@@ -105,8 +100,6 @@ def generate(out)
105100
e.signal(*args)
106101
end
107102

108-
e.constants = @constants
109-
110103
e.behavior do |b|
111104
b.process [:clock, :reset, :state] do |p|
112105
if @reset

lib/computer_build/vhdl.rb

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ def initialize(name, body)
7878
@signals = []
7979
@types = []
8080
@components = []
81-
@constants = []
8281
body[self]
8382
end
8483

@@ -103,10 +102,6 @@ def component(*args, &body)
103102
@components << Component.new(*args, &body)
104103
end
105104

106-
def constants=(consts)
107-
@constants = consts
108-
end
109-
110105
def generate(out=$stdout)
111106
out.puts "ENTITY #{@name} IS"
112107
out.puts "PORT("
@@ -119,7 +114,6 @@ def generate(out=$stdout)
119114
@types.each {|t| t.generate(out, 1)}
120115
@signals.each {|t| t.generate(out, 1)}
121116
@components.each {|c| c.generate(out, 1)}
122-
@constants.each {|c| c.generate(out, 1)}
123117
out.puts "BEGIN"
124118
@behavior.generate(out, 1)
125119
out.puts "END arch_#{@name};"
@@ -193,18 +187,6 @@ def line
193187
end
194188
end
195189

196-
class Constant < SingleLineStatement
197-
def initialize(name, type, value)
198-
@name = name
199-
@type = type
200-
@value = value
201-
end
202-
203-
def line
204-
"CONSTANT #{@name} : #{@type} := #{quoted(@value)};"
205-
end
206-
end
207-
208190
class Behavior
209191
include StatementBlock
210192

src/computer_build.clj

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,19 @@
1010
(defn wr [port]
1111
(keyword (str "wr_" (name port))))
1212

13+
(defn binary* [accumulator num]
14+
(let [last-bit (if (even? num) "0" "1")]
15+
(cond
16+
(= 0 num) (str "0" accumulator)
17+
(= 1 num) (str "1" accumulator)
18+
true (recur (str last-bit accumulator) (int (/ num 2))))))
19+
20+
(defn binary [width num]
21+
"Convert number to binary literal format expected in VHDL"
22+
(let [value (binary* "" num)
23+
length (count value)]
24+
(str (apply str (repeat (- width length) "0")) value)))
25+
1326
(defn alu-op-to-opcode [op]
1427
(if op
1528
(cond
@@ -56,7 +69,7 @@
5669
(defn make-states-for-instruction [[_ instruction-name & RTLs]]
5770
(let [microcode (flatten-1 (map rtl-to-microcode RTLs))
5871
last-index (- (count microcode) 1)
59-
make-state (fn [body index]
72+
link-state (fn [body index]
6073
{(name-for-state instruction-name index)
6174
; add next state to instruction body
6275
(assoc body
@@ -68,7 +81,7 @@
6881
(name-for-state
6982
instruction-name
7083
(+ index 1))))})]
71-
(apply merge (map make-state microcode (iterate inc 0)))))
84+
(apply merge (map link-state microcode (iterate inc 0)))))
7285

7386
(defn make-states [instructions]
7487
"Given a set of instructions, create the set of states
@@ -94,6 +107,9 @@
94107
(:code state)
95108
assertions
96109
clears
110+
(if-let [const (:constant-value state)]
111+
`((<= :system_bus ~(binary 8 const)))
112+
`((<= :system_bus ~(apply str (repeat 8 "Z")))))
97113
`((<= :alu_operation ~(alu-op-to-opcode (:alu_op state))))))))
98114

99115
(defn control-unit [instructions]
@@ -115,7 +131,7 @@
115131
control-signals (set (apply concat (map
116132
(fn [[_ body]] (:control-signals body))
117133
states)))
118-
inputs {:reset std-logic :system_bus (std-logic-vector 7 0)}
134+
inputs {:reset std-logic}
119135
outputs (assoc
120136
(zipmap control-signals (repeat (count control-signals) std-logic))
121137
:alu_operation (std-logic-vector 2 0))]
@@ -125,11 +141,14 @@
125141
inputs
126142
; outputs
127143
outputs
144+
; input/outputs
145+
{:system_bus (std-logic-vector 7 0)}
128146
; signals
129147
{ :opcode (std-logic-vector (- opcode-width 1) 0) }
130148
; reset
131149
(list* '(<= :alu_operation "000")
132150
'(goto :fetch)
151+
'(<= :system_bus "ZZZZZZZZ")
133152
(map #(list 'low %) control-signals))
134153
; states
135154
(mapmap (partial realize-state control-signals) states)
@@ -216,7 +235,9 @@
216235
(:rd :in ~std-logic))
217236

218237
(component :control_unit
219-
~@(concat (map input control-in) (map output control-out)))
238+
~@(concat (map input control-in)
239+
(map output control-out)
240+
`((:system_bus :inout ~(std-logic-vector 7 0)))))
220241
]
221242
; architecture
222243
[
@@ -232,6 +253,6 @@
232253
:wr_alu_a :wr_alu_b :rd_alu)
233254
(instance :control_unit "control0"
234255
; same ports as the control signals we got
235-
~@(map first (concat control-in control-out)))
256+
~@(map first (concat control-in control-out)) :system_bus)
236257
(<= :bus_inspection :system_bus)
237258
]))))))

src/computer_build/state_machine.clj

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,16 @@
3232
~(second transition))
3333
[(<= ~state-variable ~(state-from-name (last transition)))])))
3434

35-
(defn state-machine [name inputs outputs signals reset states transitions]
35+
(defn state-machine [name inputs outputs inouts signals reset states transitions]
3636
"Create a state machine that operates from the given inputs, triggering
3737
the specified transitions to the listed states that generate outputs on
3838
the signals in the outputs array"
3939
(let [inports (reformat-ports inputs :in)
40-
outports (reformat-ports outputs :out)]
40+
outports (reformat-ports outputs :out)
41+
inoutports (reformat-ports inouts :inout)]
4142
`(entity ~name
4243
; Ports
43-
~(concat ['(:clock :in "std_logic")] inports outports)
44+
~(concat ['(:clock :in "std_logic")] inports outports inoutports)
4445
; Definitions
4546
((deftype "STATE_TYPE"
4647
~(map #(str "state_" (keyword-to-str %)) (keys states)))

0 commit comments

Comments
 (0)