update boothmul properly; add clean to make; hardware notes
This commit is contained in:
parent
f6a4a6bbea
commit
e1d09495da
|
@ -0,0 +1,14 @@
|
||||||
|
This document is for recording notes on measurements done on Upslion
|
||||||
|
running on actual FPGAs.
|
||||||
|
|
||||||
|
Commit: `9c2731ad8d794d0b3c46999a40f0064f2b020c69`
|
||||||
|
FPGA: Arty A7-100T
|
||||||
|
F4PGA commit: `f43bb728b1bd9ef3807ef65bcf6b6629e0fa71f5`
|
||||||
|
|
||||||
|
ADCs:
|
||||||
|
|
||||||
|
SPI clocks take about 10ns to start going up and down from low voltage. They
|
||||||
|
rise to about 500mV in that time. MISO oscillates up and down up to 50mV with
|
||||||
|
no data present, rising and stays at that until it oscillates down. Should not
|
||||||
|
be a problem. Probably capacitance/crosstalk. Ringing of about 40mV on clock
|
||||||
|
and SS.
|
|
@ -10,6 +10,7 @@ build/digilent_arty/digilent_arty.bit: soc.py
|
||||||
python3 soc.py
|
python3 soc.py
|
||||||
clean:
|
clean:
|
||||||
rm -rf build csr.json overlay.config overlay.dts pin_io.h
|
rm -rf build csr.json overlay.config overlay.dts pin_io.h
|
||||||
|
cd rtl && make clean
|
||||||
overlay.dts overlay.cmake: csr.json litex_json2dts_zephyr.py
|
overlay.dts overlay.cmake: csr.json litex_json2dts_zephyr.py
|
||||||
# NOTE: Broken in LiteX 2022.4.
|
# NOTE: Broken in LiteX 2022.4.
|
||||||
$(DEVICETREE_GEN_DIR)/litex_json2dts_zephyr.py --dts overlay.dts --config overlay.cmake csr.json
|
$(DEVICETREE_GEN_DIR)/litex_json2dts_zephyr.py --dts overlay.dts --config overlay.cmake csr.json
|
||||||
|
|
|
@ -49,7 +49,7 @@ obj_dir/Vcontrol_loop_sim_top: obj_dir/Vcontrol_loop_sim_top.mk control_loop_cmd
|
||||||
####### Codegen ########
|
####### Codegen ########
|
||||||
|
|
||||||
include ../common.makefile
|
include ../common.makefile
|
||||||
CODEGEN_FILES=control_loop_cmds.h boothmul.v control_loop_math.v control_loop.v control_loop_cmds.vh
|
CODEGEN_FILES=control_loop_cmds.h boothmul_preprocessed.v control_loop_math.v control_loop.v control_loop_cmds.vh
|
||||||
codegen: ${CODEGEN_FILES}
|
codegen: ${CODEGEN_FILES}
|
||||||
control_loop_cmds.vh: control_loop_cmds.m4
|
control_loop_cmds.vh: control_loop_cmds.m4
|
||||||
m4 -P control_loop_cmds.vh.m4 > control_loop_cmds.vh
|
m4 -P control_loop_cmds.vh.m4 > control_loop_cmds.vh
|
||||||
|
|
|
@ -1,146 +0,0 @@
|
||||||
m4_changequote(`⟨', `⟩')
|
|
||||||
m4_changecom(⟨/*⟩, ⟨*/⟩)
|
|
||||||
/* Booth Multiplication v1.0
|
|
||||||
* Written by Peter McGoron, 2022.
|
|
||||||
*
|
|
||||||
* This source describes Open Hardware and is licensed under the
|
|
||||||
* CERN-OHL-W v2.
|
|
||||||
* You may redistribute and modify this documentation and make products using
|
|
||||||
* it under the terms of the CERN-OHL-W v2 (https:/cern.ch/cern-ohl), or, at
|
|
||||||
* your option, any later version.
|
|
||||||
*
|
|
||||||
* This documentation is distributed WITHOUT ANY EXPRESS OR IMPLIED WARRANTY,
|
|
||||||
* INCLUDING OF MERCHANTABILITY, SATISFACTORY QUALITY AND FITNESS FOR
|
|
||||||
* A PARTICULAR PURPOSE. Please see the CERN-OHL-W v2 for applicable
|
|
||||||
* conditions.
|
|
||||||
*
|
|
||||||
* Source location: https://software.mcgoron.com/peter/boothmul
|
|
||||||
*/
|
|
||||||
|
|
||||||
module boothmul
|
|
||||||
#(
|
|
||||||
parameter A1_LEN = 32,
|
|
||||||
parameter A2_LEN = 32,
|
|
||||||
// AZLEN_SIZ = floor(log2(A2_LEN + 2) + 1).
|
|
||||||
// It must be able to store A2_LEN + 2.
|
|
||||||
parameter A2LEN_SIZ = 6
|
|
||||||
)
|
|
||||||
(
|
|
||||||
input clk,
|
|
||||||
input arm,
|
|
||||||
input [A1_LEN-1:0] a1,
|
|
||||||
input [A2_LEN-1:0] a2,
|
|
||||||
m4_define(M4_OUT_LEN, (A1_LEN + A2_LEN))
|
|
||||||
output [M4_OUT_LEN-1:0] outn,
|
|
||||||
`ifdef DEBUG
|
|
||||||
output [M4_OUT_LEN+1:0] debug_a,
|
|
||||||
output [M4_OUT_LEN+1:0] debug_s,
|
|
||||||
output [M4_OUT_LEN+1:0] debug_p,
|
|
||||||
output [A2LEN_SIZ-1:0] debug_state,
|
|
||||||
`endif
|
|
||||||
output reg fin
|
|
||||||
);
|
|
||||||
|
|
||||||
/***********************
|
|
||||||
* Booth Parameters
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
m4_define(M4_REG_LEN, (M4_OUT_LEN + 2))
|
|
||||||
|
|
||||||
/* The Booth multiplication algorithm is a sequential algorithm for
|
|
||||||
* twos-compliment integers.
|
|
||||||
*
|
|
||||||
* Let REG_LEN be equal to 1 + len(a1) + len(a2) + 1.
|
|
||||||
* Let P, S, and A be of length REG_LEN.
|
|
||||||
* Let A = a1 << len(a2) + 1, where a1 sign extends to the upper bit.
|
|
||||||
* Let S = -a1 << len(a2) + 1, where a1 sign extens to the upper bit.
|
|
||||||
* Let P = a2 << 1.
|
|
||||||
*
|
|
||||||
* Repeat the following len(a2) times:
|
|
||||||
* case(P[1:0])
|
|
||||||
* 2'b00, 2'b11: P <= P >>> 1;
|
|
||||||
* 2'b01: P <= (P + A) >>> 1;
|
|
||||||
* 2'b10: P <= (P + S) >>> 1;
|
|
||||||
* endcase
|
|
||||||
* The final value is P[REG_LEN-2:1].
|
|
||||||
*
|
|
||||||
* Wires and registers of REG_LEN length are organized like:
|
|
||||||
*
|
|
||||||
* /Overflow bit
|
|
||||||
* [M][ REG_LEN ][0]
|
|
||||||
* [M][ A1_LEN ][ A2_LEN ][0]
|
|
||||||
*/
|
|
||||||
|
|
||||||
reg [A1_LEN-1:0] a1_reg;
|
|
||||||
|
|
||||||
wire [M4_REG_LEN-1:0] a;
|
|
||||||
assign a[A2_LEN:0] = 0;
|
|
||||||
assign a[M4_REG_LEN-2:A2_LEN+1] = a1_reg;
|
|
||||||
assign a[M4_REG_LEN-1] = a1_reg[A1_LEN-1];
|
|
||||||
wire signed [M4_REG_LEN-1:0] a_signed;
|
|
||||||
assign a_signed = a;
|
|
||||||
|
|
||||||
wire [M4_REG_LEN-1:0] s;
|
|
||||||
assign s[A2_LEN:0] = 0;
|
|
||||||
assign s[M4_REG_LEN-1:A2_LEN+1] = ~{a1_reg[A1_LEN-1],a1_reg} + 1;
|
|
||||||
wire signed [M4_REG_LEN-1:0] s_signed;
|
|
||||||
assign s_signed = s;
|
|
||||||
|
|
||||||
reg [M4_REG_LEN-1:0] p;
|
|
||||||
wire signed [M4_REG_LEN-1:0] p_signed;
|
|
||||||
assign p_signed = p;
|
|
||||||
|
|
||||||
assign outn = p[M4_REG_LEN-2:1];
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* Loop Implementation
|
|
||||||
*********************/
|
|
||||||
|
|
||||||
reg[A2LEN_SIZ-1:0] loop_accul = 0;
|
|
||||||
|
|
||||||
`ifdef DEBUG
|
|
||||||
assign debug_a = a;
|
|
||||||
assign debug_s = s;
|
|
||||||
assign debug_p = p;
|
|
||||||
assign debug_state = loop_accul;
|
|
||||||
`endif
|
|
||||||
|
|
||||||
always @ (posedge clk) begin
|
|
||||||
if (!arm) begin
|
|
||||||
loop_accul <= 0;
|
|
||||||
fin <= 0;
|
|
||||||
end else if (loop_accul == 0) begin
|
|
||||||
p[0] <= 0;
|
|
||||||
p[A2_LEN:1] <= a2;
|
|
||||||
p[M4_REG_LEN-1:A2_LEN+1] <= 0;
|
|
||||||
|
|
||||||
a1_reg <= a1;
|
|
||||||
|
|
||||||
loop_accul <= loop_accul + 1;
|
|
||||||
/* verilator lint_off WIDTH */
|
|
||||||
end else if (loop_accul < A2_LEN + 1) begin
|
|
||||||
/* verilator lint_on WIDTH */
|
|
||||||
/* The loop counter starts from 1, so it must go to
|
|
||||||
* A2_LEN + 1 exclusive.
|
|
||||||
* (i = 0; i < len; i++)
|
|
||||||
* becomes (i = 1; i < len + 1; i++)
|
|
||||||
*/
|
|
||||||
loop_accul <= loop_accul + 1;
|
|
||||||
case (p[1:0])
|
|
||||||
2'b00, 2'b11: p <= p_signed >>> 1;
|
|
||||||
2'b10: p <= (p_signed + s_signed) >>> 1;
|
|
||||||
2'b01: p <= (p_signed + a_signed) >>> 1;
|
|
||||||
endcase
|
|
||||||
end else begin
|
|
||||||
fin <= 1;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
`ifdef BOOTH_SIM
|
|
||||||
initial begin
|
|
||||||
$dumpfile("booth.vcd");
|
|
||||||
$dumpvars;
|
|
||||||
end
|
|
||||||
`endif
|
|
||||||
|
|
||||||
endmodule
|
|
|
@ -30,7 +30,7 @@ io = [
|
||||||
("test_clock", 0, Pins("P18"), IOStandard("LVCMOS33"))
|
("test_clock", 0, Pins("P18"), IOStandard("LVCMOS33"))
|
||||||
]
|
]
|
||||||
|
|
||||||
# TODO: Generate widths based off of include files (m4 generated)
|
# TODO: Assign widths to ADCs here using parameters
|
||||||
|
|
||||||
class Base(Module, AutoCSR):
|
class Base(Module, AutoCSR):
|
||||||
""" The subclass AutoCSR will automatically make CSRs related
|
""" The subclass AutoCSR will automatically make CSRs related
|
||||||
|
@ -190,7 +190,7 @@ class CryoSNOM1SoC(SoCCore):
|
||||||
platform.add_source("rtl/spi/spi_master_ss_no_read_preprocessed.v")
|
platform.add_source("rtl/spi/spi_master_ss_no_read_preprocessed.v")
|
||||||
platform.add_source("rtl/control_loop/sign_extend.v")
|
platform.add_source("rtl/control_loop/sign_extend.v")
|
||||||
platform.add_source("rtl/control_loop/intsat.v")
|
platform.add_source("rtl/control_loop/intsat.v")
|
||||||
platform.add_source("rtl/control_loop/boothmul.v")
|
platform.add_source("rtl/control_loop/boothmul_preprocessed.v")
|
||||||
platform.add_source("rtl/control_loop/control_loop_math.v")
|
platform.add_source("rtl/control_loop/control_loop_math.v")
|
||||||
platform.add_source("rtl/control_loop/control_loop.v")
|
platform.add_source("rtl/control_loop/control_loop.v")
|
||||||
platform.add_source("rtl/waveform/bram_interface_preprocessed.v")
|
platform.add_source("rtl/waveform/bram_interface_preprocessed.v")
|
||||||
|
|
Loading…
Reference in New Issue