17 use Device
::SerialPort
;
19 my $port = Device
::SerialPort
->new($ARGV[0] // '/dev/ttyUSB1') or die "$!";
21 #$port->baudrate(4000000);
22 $port->parity('none');
25 $port->handshake('none');
26 $port->read_const_time(2000);
28 $port->write_settings or die "$!";
32 use Time
::HiRes qw
/sleep/;
35 #sysopen $port, '/dev/ttyUSB1', O_SYNC | O_RDWR or die "$!";
38 use parent qw
/Exporter/;
39 our @EXPORT = qw
/loada loadb store write_verilog alu_select_a alu_select_b alu_select_f alu_zero flag_zero flag_news alu_xor alu_xnor alu_or alu_of_function aluc_add alus_add aluc_addAF alus_addAF alu2 alu3 add addC loadi storei ledm ledi route chip_select/;
40 our @EXPORT_OK = qw
/loada loadb store write_verilog alu_select_a alu_select_b alu_select_f alu_zero flag_zero flag_news alu_xor alu_xnor alu_or alu_of_function aluc_add alus_add aluc_addAF alus_addAF alu2 alu3 add addC loadi storei ledm ledi route chip_select/;
42 use File
::Slurp
::Tiny
'write_file';
50 my $binary = pack 'vCC', @cmd{qw/I mem_addr op/}; # we ignore CS for now
51 my $length = length $binary;
52 my $wrote = syswrite $port, $binary, $length;
54 # say "Wrote $wrote of $length bytes";
55 if ($cmd{op} == OP_READ) {
57 my $count_in = sysread $port, $string_in, 2;
58 my @memory = unpack 'v*', $string_in;
73 # by default instructions are for all 4 chips to execute
79 my $op_cs = $cmd{op
} + ($CS << 4);
81 my $binary = pack 'vCC', $cmd{I
}, $cmd{mem_addr
}, $op_cs;
82 my $hex = reverse unpack 'h*', $binary;
83 # say "$rom_cnt: data <= 32'h$hex;";
89 my ($new_cs, $sub) = @_;
96 { I
=> 0, mem_addr
=> 0, op
=> OP_NOP
}
100 my ($addr, $flagr, $bsel, $aluc) = @_;
106 { I
=> $I, mem_addr
=> $addr, op
=> OP_LOADA
}
110 my ($addr, $cond, $inv, $alus) = @_;
116 { I
=> $I, mem_addr
=> $addr, op
=> OP_LOADB
}
121 # send_ { I => 0, mem_addr => $addr, op => OP_READ, CS => 1 }
125 my ($addr, $flagw, $edge_, $cube) = @_;
131 { I
=> $I, mem_addr
=> $addr, op
=> OP_STORE
}
137 { I
=> $I, mem_addr
=> $addr, op
=> OP_LOADI
}
141 my ($addr, $dest_addr, $led) = @_;
146 { I
=> $I, mem_addr
=> $addr, op
=> OP_ROUTE
}
152 { I
=> $I, mem_addr
=> $addr, op
=> OP_STOREI
}
156 my ($addr, $mode, $offset_leds) = @_;
157 my $I = $offset_leds;
160 { I
=> $I, mem_addr
=> $addr, op
=> OP_LED
}
164 my ($addr, $offset) = @_;
166 led
$addr, 1, $offset;
177 sub flag_news
{ 8 + $_[0] }
203 sub alu_of_function
(&) {
207 local $a = ($i & 4) >> 2;
208 local $b = ($i & 2) >> 1;
210 $alu += ($fun->() ?
1 : 0) << $i;
215 sub aluc_add
{ alu_of_function
{ ($a + $b + $_) & 2 } }
216 sub alus_add
{ alu_of_function
{ ($a + $b + $_) & 1 } }
218 sub aluc_addAF
{ alu_of_function
{ ($a + $_) & 2 } }
219 sub alus_addAF
{ alu_of_function
{ ($a + $_) & 1 } }
221 sub alu_or
{ alu_of_function
{ $a | $b | $_ } }
223 sub alu_and
{ alu_of_function
{ $a & $b & $_ } }
226 die "alus_add != alu_xor" unless alus_add
== alu_xor
;
227 die "bad alu_select_f" unless alu_select_f
== alu_of_function
{ $_ };
231 my ($aluc, $alus, $addrA, $addrB, $flagr, $flagw, $cond, $inv) = @_;
232 loada
$addrA, $flagr, 0, $aluc;
233 loadb
$addrB, $cond, $inv, $alus;
234 store
$addrA, $flagw, 0, 0;
238 my ($aluc, $alus, $addrA, $addrB, $addrC, $flagr, $flagw) = @_;
239 loada
$addrA, $flagr, 0, $aluc;
240 loadb
$addrB, 0, 1, $alus;
241 store
$addrC, $flagw, 0, 0;
245 my ($addrA, $addrC) = @_;
246 alu3 alu_zero
, alu_select_a
, $addrA, $addrA, $addrC, flag_zero
, flag_zero
250 my ($addrA, $addrB, $addrC, $flag_carry) = @_;
251 alu3 aluc_add
, alus_add
, $addrA, $addrB, $addrC, flag_zero
, $flag_carry;
255 my ($addrA, $addrB, $addrC, $flag_carry) = @_;
256 alu3 aluc_add
, alus_add
, $addrA, $addrB, $addrC, $flag_carry, $flag_carry;
260 my ($addrA, $addrB, $addrC) = @_;
261 alu3 alu_zero
, alu_xor
, $addrA, $addrB, $addrC, flag_zero
, flag_zero
;
265 my ($addrA, $addrB, $addrC) = @_;
266 alu3 alu_zero
, alu_and
, $addrA, $addrB, $addrC, flag_zero
, flag_zero
;
269 # news_gen face partea de mijloc
270 # news_[mf][mf] face primul alu3, apeleaza news_gen, apoi face ultimul alu3
272 my ($nX, $nY, $dest) = @_;
289 if ($nX || $nY) { # not the last go
290 alu3 alu_select_f
, alu_select_a
, 0, 0, 0, flag_news
($direction), flag_zero
291 } elsif (exists $dest{address
}) {
292 alu3 alu_select_f
, alu_select_f
, 0, 0, $dest{address
}, flag_news
($direction), flag_zero
293 } elsif (exists $dest{flag
}) {
294 alu3 alu_select_f
, alu_select_a
, 0, 0, 0, flag_news
($direction), $dest{flag
}
296 die "No destination address nor flag given to [news_generic]\n"
302 my ($addrIN, $addrOUT, $nX, $nY) = @_;
303 alu3 alu_select_a
, alu_select_a
, $addrIN, 0, $addrIN, flag_zero
, flag_zero
;
304 news_generic
$nX, $nY, {address
=> $addrOUT};
308 my ($addrIN, $flagOUT, $nX, $nY) = @_;
309 alu3 alu_select_a
, alu_select_a
, $addrIN, 0, $addrIN, flag_zero
, flag_zero
;
310 news_generic
$nX, $nY, {flag
=> $flagOUT};
314 my ($flagIN, $addrOUT, $nX, $nY) = @_;
315 alu3 alu_select_f
, alu_select_a
, 0, 0, 0, $flagIN, flag_zero
;
316 news_generic
$nX, $nY, {address
=> $addrOUT};
320 my ($flagIN, $flagOUT, $nX, $nY) = @_;
321 alu3 alu_select_f
, alu_select_a
, 0, 0, 0, $flagIN, flag_zero
;
322 news_generic
$nX, $nY, {flag
=> $flagOUT};
This page took 0.037303 seconds and 4 git commands to generate.