Вуаля!
Итак, моя модель MIPS начала выдавать первые выборки (если возвращать NOP ;).
Я добавил тест, вот результат его запуска:
Мы всегда передаём 0 в качестве результата выборки, в системе команд MIPS это NOP, поэтому наш процессор последовательно перебирает адреса команд.
(достаточно сложная система вдруг заработала с первого раза, хоть и на простом тесте)
Что же там происходит.
Описание функции на Хаскеле сильно напоминает описание цифрового блока: переменные как провода, функции как блоки, сравнение с образцом и условные операторы дополняют обычные выражения над проводами, наподобие сложения, вычитания, деления и прочих.
Однако, в обычной функции отсутствует понятие (дискретного) времени, она не может напрямую работать с бесконечными списками данных. В основном, это ограничение операции сравнения с образцом case: если я сравниваю со значением, погруженным в конструктор (бесконечного списка), то мне надо этот конструктор разобрать. Все остальные операции могут быть подняты на бесконечные списки простой перегрузкой с помощью map_S, zipWith_S и тп.
Поэтому для введения дискретного времени необходимо прозрачно поднять эти операции. Это выполняет модуль Trans в каталоге streams, функцию transform которого можно использовать для проведения такого преобразования.
Преобразования оставляют исходные функции. Их можно рассматривать, как самый первый такт работы системы. А если ваша система сделана модульно и в ней разнесены функции, вычисляющие значения и функции, защёлкивающие значения - содержащие функцию register, - то тестирование сведётся к тестированию первой из них. На дискретное время всё будет распространено довольно прозрачно.
Вот кусочек исходного текста:
Если кому интересно, то при работе transform создаётся trans_log, куда пишутся результаты преобразований. Однако там слишком много информации.
Что хочу сделать.
Надо сделать ассемблер MIPS и запустить пару программ посложнее.
Хочу сделать ведение отчётов. Чтобы можно было написать в преобразуемой функции что-то вида
После того, как заработает модель MIPS на реальной программе, я хочу сделать создание текста на настоящем HDL в виде иерархии сущностей. Само собой, сразу должен получаться синтезируемый код. Пока в качестве основного претендента выступает VHDL, он поудобней будет, хотя и многословен. Вариант - SystemC, для повышения скорости моделирования.
Далее преобразование функции в конвейер (чтобы поднять тактовую частоту, будет и для модели на бесконечных списках и для синтезируемого HDL) и тому подобные мелкие улучшения.
Я добавил тест, вот результат его запуска:
*MIPS_with_mem> fetchesOfMIPSWithSeroesMemory_S 40000000 40000004 40000008 4000000c 40000010 40000014 40000018 4000001c 40000020 40000024 *MIPS_with_mem>(запускать надо "ghci -fcontext-stack=100 -istreams -icommon MIPS_with_mem.hs")
Мы всегда передаём 0 в качестве результата выборки, в системе команд MIPS это NOP, поэтому наш процессор последовательно перебирает адреса команд.
(достаточно сложная система вдруг заработала с первого раза, хоть и на простом тесте)
Что же там происходит.
Описание функции на Хаскеле сильно напоминает описание цифрового блока: переменные как провода, функции как блоки, сравнение с образцом и условные операторы дополняют обычные выражения над проводами, наподобие сложения, вычитания, деления и прочих.
Однако, в обычной функции отсутствует понятие (дискретного) времени, она не может напрямую работать с бесконечными списками данных. В основном, это ограничение операции сравнения с образцом case: если я сравниваю со значением, погруженным в конструктор (бесконечного списка), то мне надо этот конструктор разобрать. Все остальные операции могут быть подняты на бесконечные списки простой перегрузкой с помощью map_S, zipWith_S и тп.
Поэтому для введения дискретного времени необходимо прозрачно поднять эти операции. Это выполняет модуль Trans в каталоге streams, функцию transform которого можно использовать для проведения такого преобразования.
Преобразования оставляют исходные функции. Их можно рассматривать, как самый первый такт работы системы. А если ваша система сделана модульно и в ней разнесены функции, вычисляющие значения и функции, защёлкивающие значения - содержащие функцию register, - то тестирование сведётся к тестированию первой из них. На дискретное время всё будет распространено довольно прозрачно.
Вот кусочек исходного текста:
cond = case cmd of JALR rs rd -> True JR rs -> True ...Вот, как он поднимается на бесконечные списки:
cond_14 = S.map_S (\caseExprVar_15 -> case caseExprVar_15 of MIPS.JALR rs_16 rd_17 -> GHC.Bool.True MIPS.JR rs_18 -> GHC.Bool.True ...Всё незамысловато.
Если кому интересно, то при работе transform создаётся trans_log, куда пишутся результаты преобразований. Однако там слишком много информации.
Что хочу сделать.
Надо сделать ассемблер MIPS и запустить пару программ посложнее.
Хочу сделать ведение отчётов. Чтобы можно было написать в преобразуемой функции что-то вида
currentAddressTwoLeastBits = report (currAddr .&. 3)
и в результаты работы, в выходы функции, попадали бы все такие report в виде строки "currentAddressTwoLeastBits = 3".После того, как заработает модель MIPS на реальной программе, я хочу сделать создание текста на настоящем HDL в виде иерархии сущностей. Само собой, сразу должен получаться синтезируемый код. Пока в качестве основного претендента выступает VHDL, он поудобней будет, хотя и многословен. Вариант - SystemC, для повышения скорости моделирования.
Далее преобразование функции в конвейер (чтобы поднять тактовую частоту, будет и для модели на бесконечных списках и для синтезируемого HDL) и тому подобные мелкие улучшения.