Sep 16, 2020 09:34
Или как минимазировать ресурсы в АЛУ процессора.
Нередко замечал в коде на верилог для fpga частое использование операции +. Чуть ли не в каждом пункте case. Это привело меня к мысли, что использовать чужой код на верилоге может быть менее привлекательной идей чем написать свой собственной код.
Поэтому я попытался своими силами реализовать АЛУ на верилоге, но так, чтобы ресурсы использовались по минимуму. И у меня получилось реализовать шесть операций на одном сумматоре. В зависимости от операции (ADD, ADC, SUB, SBB, INC, DEC) второй операнд и carryin коммутируются либо на входной операнд либо, на ноль, затем этот скоммутированный операнд повторно коммутируется, где выбирается либо он сам либо его инверсия.
Таким образом мы настраиваем функцию с помощью четырех параметров.
На верилоге это выглядит так:
assign b0 = zero_b ? 8'b0 : b_i;
assign b = inv_b ? ~b0 : b0;
assign carryin0 = zero_c ? 1'b0 : c_i;
assign carryin = inv_c ? ~carryin0 : carryin0;
/* verilator lint_off WIDTH */
assign sum = a_i + b + carryin;
/* verilator lint_on WIDTH */
//...
// ...внутри always
case (cmd)
// ALU_CMD_ADC correspond to default settings
`ALU_CMD_ADD:
zero_c = 1'b1;
`ALU_CMD_SUB:
{inv_b,zero_c,inv_c} = 3'b111;
`ALU_CMD_SBB:
{inv_b,inv_c} = 2'b11;
`ALU_CMD_INC:
{zero_b, zero_c, inv_c} = 3'b111;
verilog,
fpga,
alu