Мысли в слух.

Dec 06, 2006 20:38

Сперва некоторое перечисление критериев/мыслей:
  • Теорию категорий подключить сразу не удастся, слишком её много. Придётся делать как всегда - ad hoc, используя идеи.
  • На первое (и довольно длительное время) можно ограничиться только синхронным дизайном без управления тактирующими линиями (такие случаи очень редки, судя по краткому опросу и исследованию).
  • Без Template Haskell не обойтись. В противном случае, не удастся использовать алгебраические типы, чего хотелось бы.
  • Судя по всему, количество идиом будет достаточно небольшим из-за необходимости их корректной трансляции. Достаточным ровно для того, чтобы не чувствовать особой скованности, это раз, и чтобы программы не раздувались, это два. Точнее: argument guards, подмножество сравнения с образцом, case, if, всякого рода умножения и сложения со сдвигами.
  • Использование TH может позволить упростить создание элементов. Например, можно сравнить типы аргументов и выходных значений, и если типы совпадают на каком-то последовательном участке, считать их состоянием, помещая их в регистры.
Пример:
$(circuit [d|counter n reset enable PosEdge
| reset = (0,0)
| enable = let n1 = n+1 in (n1,n)
| otherwise = (n,n)
|])Как вариант реализации counter. Дублирования (которое (n1,n1)) можно избежать, но это уже детали реализации.

PosEdge (который означает срабатывание по фронту тактирующего сигнала) может отделять состояние.

Что ещё интересно: тип counter получится counter :: (Num a) => a -> Bool -> Bool -> ClockEdges -> (a, a), что означает, что он параметризован типом. Значит, если мы где-то обнаружим counter, то нам придётся выяснить типы его аргументов и создать соответствующий код (counter_Int2 или counter_Int64). С одной стороны, мы не фиксируем типы, с другой стороны, придётся проводить вывод типов (заранее кричу от отчаяния;).

Для сравнения - код counter из документации на HDCaml:
let counter_design width =
(* Initialize the design database. *)
start_circuit "counter_example";

(* Define the top-level inputs. *)
let enable = input "enable" 1 in

(* Start a sub-circuit. *)
circuit "counter";

(* Instantiate the counter. Label the enable inside the sub-circuit to aid in debugging. *)
let count = counter width ("enable" -- enable) in

(* Close the sub-circuit. *)
endcircuit ();

(* Define the top-level outputs. *)
output "count" count;

(* Fetch the circuit database. *)
let circuit = get_circuit () in

(* Generate a Verilog netlist. *)
Verilog.output_netlist circuit;

(* Generate a SystemC model. *)
Systemc.output_model circuit;

(* Open a VCD channel and simulate the counter. *)
let vcd = open_out "counter_example.vcd" in
let sim, inputs, outputs = Simulate.create circuit vcd in

(* Fetch the enable input and set it high. *)
let enable = List.assoc "enable" inputs in
enable.(0) <- 1;

(* Run a few cycles. *)
Simulate.cycle sim;
Simulate.cycle sim;
Simulate.cycle sim;
Simulate.cycle sim;

(* Disable the counter. *)
enable.(0) <- 0;
Simulate.cycle sim;
Simulate.cycle sim;

(* Re-enable the counter. *)
enable.(0) <- 1;
Simulate.cycle sim;
Simulate.cycle sim;

(* Reset the circuit. *)
Simulate.reset sim;
Simulate.cycle sim;
Simulate.cycle sim;

(* Close the VCD channel. *)
close_out vcd
;;

И для справки: сравнение HDL, включая HDCaml и Confluence.

hdl, Хаскель

Previous post Next post
Up