本文实践完成模块功能开发后如何将该模块集成到chipyard中生成自己的SOC,以chipyard中示例代码GCD.scala模块为例集成到chipyard中的SOC如下图。
使用该模块理由在于该模块定义了寄存器,并且可以通过参数定制接口类型如AXI4接口或者TLINK接口,在GCD模块默认地址为0x1000,为了展示例化时通过参数传递挂载总线地址,为此修改了GCD.scala如下接口代码默认修改为0x2000,在例化时如果不传递新参数,会将默认的地址0x1000修改为这里设置的默认值0x2000
在配置文件chipyard/fpga/src/main/scala/vcu118/Configs.scala中例化GCD模块并默认传递如下参数,当然这里本人是想GCD地址分配到0x64002000,跟chipyard默认配置的SPI和UART地址空间接近。传递后两项参数纯属多余,但如果例化想跟默认不一致时可以这里修改对应的参数值。
修改完成后,执行如下命令可以生成Xilinx的vcu118开发板支持的verilog代码
生成后gcd模块挂载到tlink总线0x64002000地址空间上
对应linux下的dts文件
dts-v1/;/ {
#address-cells = <1>;
#size-cells = <1>;
compatible = "ucb-bar,chipyard-dev";
model = "ucb-bar,chipyard";
L25: aliases {
serial0 = &L16;
};
L9: chosen {
stdout-path = &L16;
};
L24: cpus {
#address-cells = <1>;
#size-cells = <0>;
timebase-frequency = <1000000>;
L6: cpu@0 {
clock-frequency = <0>;
compatible = "sifive,rocket0", "riscv";
d-cache-block-size = <64>;
d-cache-sets = <64>;
d-cache-size = <16384>;
d-tlb-sets = <1>;
d-tlb-size = <32>;
device_type = "cpu";
hardware-exec-breakpoint-count = <1>;
i-cache-block-size = <64>;
i-cache-sets = <64>;
i-cache-size = <16384>;
i-tlb-sets = <1>;
i-tlb-size = <32>;
mmu-type = "riscv,sv39";
next-level-cache = <&L3>;
reg = <0x0>;
riscv,isa = "rv64imafdcZicsr_Zifencei_Zihpm_Xrocket";
riscv,pmpgranularity = <4>;
riscv,pmpregions = <8>;
status = "okay";
timebase-frequency = <1000000>;
tlb-split;
L4: interrupt-controller {
#interrupt-cells = <1>;
compatible = "riscv,cpu-intc";
interrupt-controller;
};
};
};
L11: memory@80000000 {
device_type = "memory";
reg = <0x80000000 0x80000000>;
};
L23: soc {
#address-cells = <1>;
#size-cells = <1>;
compatible = "ucb-bar,chipyard-soc", "simple-bus";
ranges;
L15: boot-address-reg@4000 {
reg = <0x4000 0x1000>;
reg-names = "control";
};
L3: cache-controller@2010000 {
cache-block-size = <64>;
cache-level = <2>;
cache-sets = <1024>;
cache-size = <524288>;
cache-unified;
compatible = "sifive,inclusivecache0", "cache";
next-level-cache = <&L11>;
reg = <0x2010000 0x1000>;
reg-names = "control";
sifive,mshr-count = <7>;
};
L8: clint@2000000 {
compatible = "riscv,clint0";
interrupts-extended = <&L4 3 &L4 7>;
reg = <0x2000000 0x10000>;
reg-names = "control";
};
L19: clock-gater@100000 {
reg = <0x100000 0x1000>;
reg-names = "control";
};
L1: error-device@3000 {
compatible = "sifive,error0";
reg = <0x3000 0x1000>;
};
L18: gcd@64002000 {
compatible = "ucb-bar,gcd";
reg = <0x64002000 0x1000>;
reg-names = "control";
};
L7: interrupt-controller@c000000 {
#interrupt-cells = <1>;
compatible = "riscv,plic0";
interrupt-controller;
interrupts-extended = <&L4 11 &L4 9>;
reg = <0xc000000 0x4000000>;
reg-names = "control";
riscv,max-priority = <3>;
riscv,ndev = <2>;
};
L14: rom@10000 {
compatible = "sifive,rom0";
reg = <0x10000 0x10000>;
reg-names = "mem";
};
L16: serial@64000000 {
clocks = <&L0>;
compatible = "sifive,uart0";
interrupt-parent = <&L7>;
interrupts = <1>;
reg = <0x64000000 0x1000>;
reg-names = "control";
};
L17: spi@64001000 {
#address-cells = <1>;
#size-cells = <0>;
clocks = <&L0>;
compatible = "sifive,spi0";
interrupt-parent = <&L7>;
interrupts = <2>;
reg = <0x64001000 0x1000>;
reg-names = "control";
L26: mmc@0 {
compatible = "mmc-spi-slot";
disable-wp;
reg = <0x0>;
spi-max-frequency = <1000000>;
voltage-ranges = <3300 3300>;
};
};
L2: subsystem_mbus_clock {
#clock-cells = <0>;
clock-frequency = <100000000>;
clock-output-names = "subsystem_mbus_clock";
compatible = "fixed-clock";
};
L0: subsystem_pbus_clock {
#clock-cells = <0>;
clock-frequency = <100000000>;
clock-output-names = "subsystem_pbus_clock";
compatible = "fixed-clock";
};
L20: tile-reset-setter@110000 {
reg = <0x110000 0x1000>;
reg-names = "control";
};
};
};
由于Linux系统环境中未安装vivado工具,不能直接生成bit文件且出现2个错误,不知到为什么但能生成verilog代码。将生成的verilog代码添加window环境的vivado工程中也能综合通过。
还有个问题就是选择useAXI4=true的时候编译报错如下图还在尝试解决中