diff options
author | Alex AUVOLAT <alex.auvolat@ens.fr> | 2013-11-06 19:22:00 +0100 |
---|---|---|
committer | Alex AUVOLAT <alex.auvolat@ens.fr> | 2013-11-06 19:22:00 +0100 |
commit | 818f81108fa30cd5a90c99df955f811fed043993 (patch) | |
tree | 1c0bc35a07a3443deb8bdceeaab3725af7284893 | |
parent | ad529541bf54d9a4339a7371208b7d328c0a449a (diff) | |
download | SystDigit-Projet-818f81108fa30cd5a90c99df955f811fed043993.tar.gz SystDigit-Projet-818f81108fa30cd5a90c99df955f811fed043993.zip |
Documented the C simulator in the README file ; added a test file.
-rw-r--r-- | README | 160 | ||||
-rw-r--r-- | csim/Makefile | 2 | ||||
-rw-r--r-- | tests/shifters.mj | 62 |
3 files changed, 206 insertions, 18 deletions
@@ -1,10 +1,12 @@ - Système Digital 2013-2014 Cours J.Vuillemin, TD T.Bourke Alex AUVOLAT (Info 2013) +Introduction +============ + Contents of the repository : ---------------------------- @@ -13,32 +15,48 @@ sched/ Input : a netlist. Output : a netlist with topologically sorted operators plus a dumbed-down version for input to the C circuit simulator + This program is also capable of a few optimisation (usually reduces netlist + size by 1/4). $ cd sched/ $ ocamlbuild main.byte -camlsim/ - A circuit simulator written in OCaml. - This program does NOT do the scheduling. The netlist must be passed through sched/ first. - $ cd camlsim/ - $ ocamlbuild simulator.byte - csim/ A circuit simulator written in C. This program does NOT do the scheduling. - This program does NOT read a netlist, it reads a specifically formatted dumbed-down netlist, that - is output by the scheduler. + This program does NOT read a netlist, it reads a specifically formatted + dumbed-down netlist, that is output by the scheduler. $ cd csim $ make +camlsim/ + A circuit simulator written in OCaml. + This program does NOT do the scheduling. The netlist must be passed through + the scheduler first. + This program is *highly incomplete* and not recomended for real use.. + $ cd camlsim/ + $ ocamlbuild simulator.byte + minijazz/ - The MiniJazz compiler (not our doing). + The MiniJazz compiler (given by the teachers). *.pdf Documentation about the project. -CONVENTION FOR BINARY VALUES +REFERENCES +---------- + + - Computer organization and design : the hardware/software interface + 4th ed + Chapters 2 to 4 + + + +INTERNALS +========= + +Convention for binary values ---------------------------- /!\ This convention is contrary to the one used in the example file nadder.mj @@ -49,15 +67,123 @@ The bit array [a_0 a_1 a_2 ... a_n-1] represents the decimal number : When represented in binary, we write the bits in the order : a_0 a_1 a_2 ... a_n-1 +Even though the normal notation for a binary number is : + a_n-1 a_n-2 ... a_0 /!\ BINARY NUMBERS ARE WRITTEN REVERSE ! +What we call a shift-left does a left shift on the representation as a binary +number, but we use the reverse notation here. Therefore in the ALU, the shift-left +should actually right-shift the bits when they are seen in the order a0, a1, ... + +The right shift is also inverted. +- left shift -> right shift +- right shift -> left shift +- left shift logical -> rigth shift logical + + +The dumbed-down netlist format +------------------------------ + +The C simulator does NOT read a properly formatted netlist, but only a file +representing it written in a simple format, that can be parsed with only calls +to `scanf`. The file is organized as follows : + +<number of variables> +<variable types and names *1> +<inputs *2> +<outputs *2> +<number of equations> +<equation list *3> + +*1 : this section contains for each variable a line in the format : +<variable width> <variable name> + +In the rest of the files, the variables are referenced by their position in the +list given in *1 (the first line gives variable #0, etc.) + +*2 : these section contain one line : +<number of inputs/outputs> [<variable number> ...] + +*3 : this section contains one line for each equation, in the following format : +<destination variable> <equation type> [<argument> ...] + +Table of equation types : + +Type# Desc Arguments +0 Arg <arg> +1 Reg <var#> +2 Not <arg> +3 Binop <op# *4> <arg> <arg> +4 Mux <arg> <arg:when false> <arg:when true> +5 Rom <addr_size> <word_size> <arg:read_addr> +6 Ram <addr_size> <word_size> <arg:read_addr> <arg:write_enable> + <arg:write_addr> <arg:data> +7 Concat <arg> <arg> +8 Slice <begin> <end> <arg> +9 Select <id> <arg> + +An argument (<arg> or <arg:*>) can be either a binary value, represented by the +bits in standard order defined above, either a reference to another variable, +with the syntax $<var_id> + +*4 : The operators are : +0 OR +1 XOR +2 AND +3 NAND + +This syntax is formalized by the reference implementation provided in the source +file csim/load.h. + +TODO : to simplify the internals, create an intermediate format where <arg> can +be nothing but a reference to another variable. All constants will then have to +be assigned to a constant-type variable that can be counted among the inputs (or +whatever - anyway, no need to recalculate them at every iteration). + + +The Input/Output format +----------------------- + +The C simulator is capable of reading inputs for each step from a file (by +default stdin, but can be redirected from a file using the -in option) and of +writing the outputs at each step to a file (by default stdout, but can be +redirected with -out). + +The input format is extremely straightforward : at each step, read a line +containing for each input variable, *in the order given in the program file*, +either a binary value (represented by a series of bits given in the standard +order), either a decimal value prefixed with a slash (/), which is then +converted to binary according to the standard representation defined above. + +The output format contains at each step one line for each output variable, in +the format : +<variable name>\t<binary representation>\t<decimal representation> +The output contains an empty line at the end of every cycle. + + +How ROMs are handled +-------------------- + +The MiniJazz language has many flaws, and one is the impossibility to specify +what is to be loaded in a ROM. One possibility (not implemented yet) would be +that each ROM-type equation uses data from a file which is found by looking at +the name of the variable that is read from the ROM. For example, if we have : + decode7_128 = ROM 4 7 _l_42_122 +which is a possible output for the MiniJazz compiler, and if the simulator is +provided with the command-line argument : + -rom decode7 path/to/decode7.rom +then the compiler will detect the prefix `decode7` in the variable name +decode7_128, and use the ROM from the file specified on the command line. + +Suggested format for the ROM files : + +<address width> <word size> +<data> + +The data is composed of 2^(address width) values separated by spaces. If they +have no prefix, they are read as binary. If they have a / prefix, they are read +as decimal (this enables the use of whichever representation is preferred). -REFERENCES ----------- - - - Computer organization and design : the hardware/software interface - 4th ed - Chapters 2 to 4 diff --git a/csim/Makefile b/csim/Makefile index c94bee2..cc88ac3 100644 --- a/csim/Makefile +++ b/csim/Makefile @@ -2,4 +2,4 @@ csim: main.o load.o sim.o gcc -o csim $^ %.o: %.c - gcc -c $< -o $@ -g + gcc -c $< -o $@ -O2 -g diff --git a/tests/shifters.mj b/tests/shifters.mj new file mode 100644 index 0000000..2fbe498 --- /dev/null +++ b/tests/shifters.mj @@ -0,0 +1,62 @@ +const word_size = 4 + +(* Transforme un fil en une nappe de n fils avec la meme valeur *) +power<n>(i) = (o:[n]) where + if n = 0 then + o = [] + else + o = power<n-1>(i) . i + end if +end where + +mux_n<n>(c, a:[n], b:[n]) = (o:[n]) where + if n = 0 then + o = [] + else + o_n1 = mux_n<n-1>(c, a[1..n-1], b[1..n-1]); + o_n = mux(c, a[0], b[0]); + o = o_n . o_n1 + end if +end where + +lshifter_n<n, p>(sh:[n], a:[p]) = (o:[p]) where + if n = 0 then + o = a + else + u = mux_n<p>(sh[n-1], a, power<2^(n-1)>(false) . a[0..p-2^(n-1)-1]); + o = lshifter_n<n-1, p>(sh[0..n-2], u) + end if +end where + +rshifter_n<n, p>(sh:[n], arith, a:[p]) = (o:[p]) where + if n = 1 then + added_bit = mux(arith, false, a[p-1]); + o = mux_n<p>(sh[0], a, a[1..p-1] . added_bit) + else + added_bit = mux(arith, false, a[p - 1]); + u = mux_n<p>(sh[n-1], a, a[2^(n-1)..p-1] . power<2^(n-1)>(added_bit)); + o = rshifter_n<n-1, p>(sh[0..n-2], arith, u) + end if +end where + +or_n<n>(a:[n],b:[n]) = (o:[n]) where + if n = 0 then + o = [] + else + o = (a[0] or b[0]) . or_n<n-1>(a[1..], b[1..]) + end if +end where + +and_each<n>(a,b:[n]) = (o:[n]) where + if n = 0 then + o = [] + else + o = (a and b[0]) . and_each<n-1>(a, b[1..]) + end if +end where + +main(sh:[2], arith, left, a:[word_size]) = (o:[word_size]) where + x = rshifter_n<2, word_size>(sh, arith, a); + xx = and_each<word_size>(not left, x); + o = xx +end where |