OR-1 dataflow CPU sketch
at 00d336d2d4b197bbb9dbbf3641f5f112bf0cf3ec 307 lines 9.5 kB view raw
1"""Parser tests for the dataflow graph assembly grammar.""" 2 3from textwrap import dedent 4 5import pytest 6from lark import exceptions, LarkError 7 8 9class TestInstDefs: 10 def test_basic_instructions(self, parser): 11 tree = parser.parse(dedent("""\ 12 &my_add <| add 13 &my_sub <| sub 14 &my_const <| const, 10 15 &my_shift <| shiftl 16 &my_not <| not 17 """)) 18 assert tree.data == "start" 19 assert len(tree.children) == 5 20 assert all(child.data == "inst_def" for child in tree.children) 21 22 def test_hex_const(self, parser): 23 tree = parser.parse(dedent("""\ 24 &mask <| const, 0xFF 25 """)) 26 assert tree.data == "start" 27 assert len(tree.children) == 1 28 assert tree.children[0].data == "inst_def" 29 30 def test_named_args(self, parser): 31 tree = parser.parse(dedent("""\ 32 &serial <| ior, dest=0x45, addr=0x91, data=0x43 33 """)) 34 assert tree.data == "start" 35 assert len(tree.children) == 1 36 assert tree.children[0].data == "inst_def" 37 38 def test_system_config(self, parser): 39 tree = parser.parse(dedent("""\ 40 &loader <| load_inst, dest=0x01, addr=0x00, data_l=0xABCD, data_h=0x1234 41 """)) 42 assert tree.data == "start" 43 assert len(tree.children) == 1 44 assert tree.children[0].data == "inst_def" 45 46 47class TestEdges: 48 def test_plain_edges(self, parser): 49 tree = parser.parse(dedent("""\ 50 &a |> &b:L 51 &a |> &b:R 52 &c |> &d, &e 53 """)) 54 assert tree.data == "start" 55 assert len(tree.children) == 3 56 assert all(child.data == "plain_edge" for child in tree.children) 57 58 def test_strong_inline_edge(self, parser): 59 tree = parser.parse(dedent("""\ 60 add &a, &b |> &c, &d 61 """)) 62 assert tree.data == "start" 63 assert len(tree.children) == 1 64 assert tree.children[0].data == "strong_edge" 65 66 def test_weak_inline_edge(self, parser): 67 tree = parser.parse(dedent("""\ 68 &c, &d sub <| &a, &b 69 """)) 70 assert tree.data == "start" 71 assert len(tree.children) == 1 72 assert tree.children[0].data == "weak_edge" 73 74 def test_fanout(self, parser): 75 tree = parser.parse(dedent("""\ 76 &splitter <| pass 77 &input |> &splitter:L 78 &splitter |> &consumer_a:L, &consumer_b:R 79 """)) 80 assert tree.data == "start" 81 assert len(tree.children) == 3 82 assert tree.children[0].data == "inst_def" 83 assert tree.children[1].data == "plain_edge" 84 assert tree.children[2].data == "plain_edge" 85 86 87class TestFunctions: 88 def test_fib_function(self, parser): 89 tree = parser.parse(dedent("""\ 90 $fib |> { 91 &const_n <| const, 10 92 &sub1 <| sub 93 &sub2 <| sub 94 &branch <| sweq 95 96 &const_n |> &branch:L 97 &const_n |> &sub1:L 98 &const_n |> &sub1:R 99 &const_n |> &sub2:R 100 &sub1 |> &recurse_a:L 101 } 102 """)) 103 assert tree.data == "start" 104 assert len(tree.children) == 1 105 assert tree.children[0].data == "func_def" 106 107 108class TestPlacement: 109 def test_pe_qualifiers(self, parser): 110 tree = parser.parse(dedent("""\ 111 &my_add|pe0 <| add 112 &result|pe1 <| pass 113 &my_add|pe0 |> &result|pe1:L 114 """)) 115 assert tree.data == "start" 116 assert len(tree.children) == 3 117 assert tree.children[0].data == "inst_def" 118 assert tree.children[1].data == "inst_def" 119 assert tree.children[2].data == "plain_edge" 120 121 def test_location_directive(self, parser): 122 tree = parser.parse(dedent("""\ 123 @data_section|sm0 124 """)) 125 assert tree.data == "start" 126 assert len(tree.children) == 1 127 assert tree.children[0].data == "location_dir" 128 129 130class TestDataDefs: 131 def test_hex_data(self, parser): 132 tree = parser.parse(dedent("""\ 133 @hello|sm0:0 = 0x05 134 @hello|sm0:1 = 'h', 'e' 135 @hello|sm0:2 = 'l', 'l' 136 """)) 137 assert tree.data == "start" 138 assert len(tree.children) == 3 139 assert all(child.data == "data_def" for child in tree.children) 140 141 def test_macro_invocation(self, parser): 142 tree = parser.parse(dedent("""\ 143 @hello = #str "hello" 144 """)) 145 assert tree.data == "start" 146 assert len(tree.children) == 1 147 assert tree.children[0].data == "data_def" 148 149 def test_multi_line_string(self, parser): 150 tree = parser.parse(dedent('''\ 151 @msg = "hello 152world" 153 ''')) 154 assert tree.data == "start" 155 assert len(tree.children) == 1 156 assert tree.children[0].data == "data_def" 157 158 def test_raw_string(self, parser): 159 tree = parser.parse(dedent("""\ 160 @path = r"no\\escapes\\here" 161 """)) 162 assert tree.data == "start" 163 assert len(tree.children) == 1 164 assert tree.children[0].data == "data_def" 165 166 def test_byte_string(self, parser): 167 tree = parser.parse(dedent("""\ 168 @raw_data = b"\\x01\\x02\\x03" 169 """)) 170 assert tree.data == "start" 171 assert len(tree.children) == 1 172 assert tree.children[0].data == "data_def" 173 174 175class TestComments: 176 def test_inline_comments(self, parser): 177 tree = parser.parse(dedent("""\ 178 &my_add <| add ; this is a comment 179 &a |> &b:L ; wire a to b left port 180 """)) 181 assert tree.data == "start" 182 assert len(tree.children) == 2 183 assert tree.children[0].data == "inst_def" 184 assert tree.children[1].data == "plain_edge" 185 186 187class TestMixedPrograms: 188 def test_mixed_program(self, parser): 189 tree = parser.parse(dedent("""\ 190 @counter|sm0:0 = 0x00 191 192 $main |> { 193 &init <| const, 0 194 &loop_add <| add 195 &cmp <| lte 196 &branch <| breq 197 &output <| iow, dest=0x01 198 199 &init |> &loop_add:L 200 &loop_add |> &cmp:L 201 &loop_add |> &output:L 202 } 203 """)) 204 assert tree.data == "start" 205 assert len(tree.children) == 2 206 assert tree.children[0].data == "data_def" 207 assert tree.children[1].data == "func_def" 208 209 210class TestSMOps: 211 def test_read_op(self, parser): 212 tree = parser.parse(dedent("""\ 213 &cell <| read 214 """)) 215 assert tree.data == "start" 216 assert len(tree.children) == 1 217 assert tree.children[0].data == "inst_def" 218 219 def test_write_op(self, parser): 220 tree = parser.parse(dedent("""\ 221 &cell <| write 222 """)) 223 assert tree.data == "start" 224 assert len(tree.children) == 1 225 assert tree.children[0].data == "inst_def" 226 227 def test_clear_op(self, parser): 228 tree = parser.parse(dedent("""\ 229 &cell <| clear 230 """)) 231 assert tree.data == "start" 232 assert len(tree.children) == 1 233 assert tree.children[0].data == "inst_def" 234 235 def test_alloc_op(self, parser): 236 tree = parser.parse(dedent("""\ 237 &cell <| alloc 238 """)) 239 assert tree.data == "start" 240 assert len(tree.children) == 1 241 assert tree.children[0].data == "inst_def" 242 243 def test_free_op(self, parser): 244 tree = parser.parse(dedent("""\ 245 &cell <| free 246 """)) 247 assert tree.data == "start" 248 assert len(tree.children) == 1 249 assert tree.children[0].data == "inst_def" 250 251 def test_rd_inc_op(self, parser): 252 tree = parser.parse(dedent("""\ 253 &cell <| rd_inc 254 """)) 255 assert tree.data == "start" 256 assert len(tree.children) == 1 257 assert tree.children[0].data == "inst_def" 258 259 def test_rd_dec_op(self, parser): 260 tree = parser.parse(dedent("""\ 261 &cell <| rd_dec 262 """)) 263 assert tree.data == "start" 264 assert len(tree.children) == 1 265 assert tree.children[0].data == "inst_def" 266 267 def test_cmp_sw_op(self, parser): 268 tree = parser.parse(dedent("""\ 269 &cell <| cmp_sw 270 """)) 271 assert tree.data == "start" 272 assert len(tree.children) == 1 273 assert tree.children[0].data == "inst_def" 274 275 276class TestSystemPragma: 277 def test_system_pragma_minimal(self, parser): 278 tree = parser.parse(dedent("""\ 279 @system pe=4, sm=1 280 """)) 281 assert tree.data == "start" 282 assert len(tree.children) == 1 283 assert tree.children[0].data == "system_pragma" 284 285 def test_system_pragma_full(self, parser): 286 tree = parser.parse(dedent("""\ 287 @system pe=2, sm=1, iram=128, ctx=2 288 """)) 289 assert tree.data == "start" 290 assert len(tree.children) == 1 291 assert tree.children[0].data == "system_pragma" 292 293 def test_system_pragma_with_hex(self, parser): 294 tree = parser.parse(dedent("""\ 295 @system pe=0x04, sm=0x01 296 """)) 297 assert tree.data == "start" 298 assert len(tree.children) == 1 299 assert tree.children[0].data == "system_pragma" 300 301 302class TestUnknownOpcodes: 303 def test_unknown_opcode_fails(self, parser): 304 with pytest.raises((exceptions.UnexpectedToken, exceptions.UnexpectedCharacters)): 305 parser.parse(dedent("""\ 306 &unknown <| foobar 307 """))