diff --git a/.github/verible.waiver b/.github/verible.waiver new file mode 100644 index 00000000..39bad59e --- /dev/null +++ b/.github/verible.waiver @@ -0,0 +1,17 @@ +# Copyright 2023 ETH Zurich and University of Bologna. +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +# Auto-generated configuration registers are waived +waive --rule=typedef-structs-unions --location="hw/system/spatz_cluster/src/spatz_cluster_peripheral/*" +waive --rule=line-length --location="hw/system/spatz_cluster/src/spatz_cluster_peripheral/*" +waive --rule=no-trailing-spaces --location="hw/system/spatz_cluster/src/spatz_cluster_peripheral/*" +waive --rule=parameter-name-style --location="hw/system/spatz_cluster/src/spatz_cluster_peripheral/*" +# Our parameters are not CamelCase +waive --rule=parameter-name-style --location="hw/ip/snitch/src/snitch_pkg.sv" +waive --rule=parameter-name-style --location="hw/ip/spatz/src/generated/spatz_pkg.sv" +# Our interfaces do not follow the interface conventions +waive --rule=interface-name-style --location="hw/ip/reqrsp_interface/src/reqrsp_intf.sv" +waive --rule=interface-name-style --location="hw/ip/tcdm_interface/src/tcdm_interface.sv" +# We have some long lines +waive --rule=line-length --location="hw/*" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cd71686e..f4654380 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,3 +1,7 @@ +# Copyright 2023 ETH Zurich and University of Bologna. +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + name: gitlab-ci on: [ push, pull_request, workflow_dispatch ] @@ -51,3 +55,4 @@ jobs: domain: iis-git.ee.ethz.ch repo: github-mirror/spatz token: ${{ secrets.GITLAB_TOKEN }} + poll-count: 2160 diff --git a/Bender.yml b/Bender.yml index c4455ee5..e51c0e3a 100644 --- a/Bender.yml +++ b/Bender.yml @@ -53,14 +53,6 @@ sources: ## hw/ip/mem_interface ## - hw/ip/mem_interface/src/mem_wide_narrow_mux.sv - - hw/ip/mem_interface/src/mem_interface.sv - - target: simulation - files: - - hw/ip/mem_interface/src/mem_test.sv - - target: test - files: - # Level 0 - - hw/ip/mem_interface/test/mem_wide_narrow_mux_tb.sv ## hw/ip/tcdm_interface ## diff --git a/README.md b/README.md index ee29aafc..0adc984b 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,7 @@ # Spatz -Spatz is a compact vector processor based on [RISC-V's Vector Extension (RVV) v1.0](https://github.com/riscv/riscv-v-spec/releases/tag/v1.0). -Spatz acts as a coprocessor of [Snitch](https://github.com/pulp-platform/snitch), a tiny 64-bit scalar core. +Spatz is a compact vector processor based on [RISC-V's Vector Extension (RVV) v1.0](https://github.com/riscv/riscv-v-spec/releases/tag/v1.0). Spatz acts as a coprocessor of [Snitch](https://github.com/pulp-platform/snitch), a tiny 64-bit scalar core. It is developed as part of the PULP project, a joint effort between ETH Zurich and the University of Bologna. ## Getting started @@ -120,3 +119,19 @@ The following directories contains third-party sources that come with their lice - `sw/snRuntime/vendor` - `sw/toolchain/` - `util/vendor` + +## Publications + +If you want to use Spatz, you can cite us: + +```bibtex +@Article{Spatz2023, + title = {Spatz: Clustering Compact RISC-V-Based Vector Units to Maximize Computing Efficiency}, + author = {Matheus Cavalcante and Matteo Perotti and Samuel Riedel and Luca Benini}, + year = {2023}, + month = sep, + eprint = {2309.5116558}, + archivePrefix = {arXiv}, + primaryClass = {cs.AR} +} +``` diff --git a/hw/ip/mem_interface/src/mem_interface.sv b/hw/ip/mem_interface/src/mem_interface.sv deleted file mode 100644 index c803b38d..00000000 --- a/hw/ip/mem_interface/src/mem_interface.sv +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright 2020 ETH Zurich and University of Bologna. -// Solderpad Hardware License, Version 0.51, see LICENSE for details. -// SPDX-License-Identifier: SHL-0.51 - -// Author: Florian Zaruba - -/// MEM Interface. -interface MEM_BUS #( - /// The width of the address. - parameter int ADDR_WIDTH = -1, - /// The width of the data. - parameter int DATA_WIDTH = -1, - /// Additional user payload on the `q` channel. - parameter type user_t = logic -); - - import reqrsp_pkg::*; - - localparam int unsigned StrbWidth = DATA_WIDTH / 8; - - typedef logic [ADDR_WIDTH-1:0] addr_t; - typedef logic [DATA_WIDTH-1:0] data_t; - typedef logic [StrbWidth-1:0] strb_t; - /// The request channel (Q). - addr_t q_addr; - /// 0 = read, 1 = write, 1 = amo fetch-and-op - logic q_write; - amo_op_e q_amo; - data_t q_data; - /// Byte-wise strobe - strb_t q_strb; - user_t q_user; - logic q_valid; - logic q_ready; - - /// The response channel (P). - data_t p_data; - - modport in ( - input q_addr, q_write, q_amo, q_user, q_data, q_strb, q_valid, - output q_ready, p_data - ); - modport out ( - output q_addr, q_write, q_amo, q_user, q_data, q_strb, q_valid, - input q_ready, p_data - ); - modport monitor ( - input q_addr, q_write, q_amo, q_user, q_data, q_strb, q_valid, - q_ready, p_data - ); - -endinterface - -/// MEM Interface for verficiation purposes. -interface MEM_BUS_DV #( - /// The width of the address. - parameter int ADDR_WIDTH = -1, - /// The width of the data. - parameter int DATA_WIDTH = -1, - /// Additional user payload on the `q` channel. - parameter type user_t = logic -) ( - input logic clk_i -); - - import reqrsp_pkg::*; - - localparam int unsigned StrbWidth = DATA_WIDTH / 8; - - typedef logic [ADDR_WIDTH-1:0] addr_t; - typedef logic [DATA_WIDTH-1:0] data_t; - typedef logic [StrbWidth-1:0] strb_t; - /// The request channel (Q). - addr_t q_addr; - /// 0 = read, 1 = write, 1 = amo fetch-and-op - logic q_write; - amo_op_e q_amo; - data_t q_data; - /// Byte-wise strobe - strb_t q_strb; - user_t q_user; - logic q_valid; - logic q_ready; - - /// The response channel (P). - data_t p_data; - - modport in ( - input q_addr, q_write, q_amo, q_user, q_data, q_strb, q_valid, - output q_ready, p_data - ); - modport out ( - output q_addr, q_write, q_amo, q_user, q_data, q_strb, q_valid, - input q_ready, p_data - ); - modport monitor ( - input q_addr, q_write, q_amo, q_user, q_data, q_strb, q_valid, - q_ready, p_data - ); - - // pragma translate_off - `ifndef VERILATOR - assert property (@(posedge clk_i) (q_valid && !q_ready |=> $stable(q_addr))); - assert property (@(posedge clk_i) (q_valid && !q_ready |=> $stable(q_write))); - assert property (@(posedge clk_i) (q_valid && !q_ready |=> $stable(q_amo))); - assert property (@(posedge clk_i) (q_valid && !q_ready |=> $stable(q_data))); - assert property (@(posedge clk_i) (q_valid && !q_ready |=> $stable(q_strb))); - assert property (@(posedge clk_i) (q_valid && !q_ready |=> $stable(q_user))); - assert property (@(posedge clk_i) (q_valid && !q_ready |=> q_valid)); - `endif - // pragma translate_on - -endinterface diff --git a/hw/ip/mem_interface/src/mem_test.sv b/hw/ip/mem_interface/src/mem_test.sv deleted file mode 100644 index 27655f51..00000000 --- a/hw/ip/mem_interface/src/mem_test.sv +++ /dev/null @@ -1,387 +0,0 @@ -// Copyright 2020 ETH Zurich and University of Bologna. -// Solderpad Hardware License, Version 0.51, see LICENSE for details. -// SPDX-License-Identifier: SHL-0.51 - -/// A set of testbench utlities for the MEM interface. -package mem_test; - - class req_t #( - parameter int AW = 32, - parameter int DW = 32, - parameter type user_t = logic - ); - rand logic [AW-1:0] addr; - rand logic write; - rand reqrsp_pkg::amo_op_e amo; - rand logic [DW-1:0] data; - rand logic [DW/8-1:0] strb; - rand user_t user; - - rand bit is_amo; - - constraint legal_amo_op_c { - amo inside { - reqrsp_pkg::AMOSwap, - reqrsp_pkg::AMOAdd, - reqrsp_pkg::AMOAnd, - reqrsp_pkg::AMOOr, - reqrsp_pkg::AMOXor, - reqrsp_pkg::AMOMax, - reqrsp_pkg::AMOMaxu, - reqrsp_pkg::AMOMin, - reqrsp_pkg::AMOMinu, - reqrsp_pkg::AMOSC} -> write == 1; - } - - // Reduce the amount of atomics. - constraint amo_reduce_c { - is_amo dist { 1:= 1, 0:= 10}; - is_amo -> amo inside { - reqrsp_pkg::AMOSwap, - reqrsp_pkg::AMOAdd, - reqrsp_pkg::AMOAnd, - reqrsp_pkg::AMOOr, - reqrsp_pkg::AMOXor, - reqrsp_pkg::AMOMax, - reqrsp_pkg::AMOMaxu, - reqrsp_pkg::AMOMin, - reqrsp_pkg::AMOMinu - }; - } - - /// Compare objects of same type. - function do_compare(req_t rhs); - return addr == rhs.addr & - write == rhs.write & - amo == rhs.amo & - data == rhs.data & - strb == rhs.strb; - endfunction - - endclass - - class rsp_t #( - parameter int DW = 32 - ); - rand logic [DW-1:0] data; - - /// Compare objects of same type. - function do_compare(rsp_t rhs); - return data == rhs.data; - endfunction - - endclass - - class mem_driver #( - parameter int AW = -1, - parameter int DW = -1, - parameter type user_t = logic, - /// Stimuli application time - parameter time TA = 0, - /// Stimuli test time - parameter time TT = 0 - ); - - typedef req_t #(.AW(AW), .DW(DW), .user_t (user_t)) req_t; - typedef rsp_t #(.DW(DW)) rsp_t; - - virtual MEM_BUS_DV #( - .ADDR_WIDTH(AW), - .DATA_WIDTH(DW), - .user_t (user_t) - ) bus; - - function new( - virtual MEM_BUS_DV #( - .ADDR_WIDTH(AW), - .DATA_WIDTH(DW), - .user_t (user_t) - ) bus - ); - this.bus = bus; - endfunction - - task reset_master; - bus.q_addr <= '0; - bus.q_write <= '0; - bus.q_amo <= reqrsp_pkg::AMONone; - bus.q_data <= '0; - bus.q_strb <= '0; - bus.q_user <= '0; - bus.q_valid <= '0; - endtask - - task reset_slave; - bus.q_ready <= '0; - bus.p_data <= '0; - endtask - - task cycle_start; - #TT; - endtask - - task cycle_end; - @(posedge bus.clk_i); - endtask - - /// Send a request. - task send_req (input req_t req); - bus.q_addr <= #TA req.addr; - bus.q_write <= #TA req.write; - bus.q_amo <= #TA req.amo; - bus.q_data <= #TA req.data; - bus.q_strb <= #TA req.strb; - bus.q_user <= #TA req.user; - bus.q_valid <= #TA 1; - cycle_start(); - while (bus.q_ready != 1) begin cycle_end(); cycle_start(); end - cycle_end(); - bus.q_addr <= #TA '0; - bus.q_write <= #TA '0; - bus.q_data <= #TA '0; - bus.q_strb <= #TA '0; - bus.q_user <= #TA '0; - bus.q_valid <= #TA 0; - endtask - - /// Send a response. - task send_rsp (input rsp_t rsp); - bus.p_data <= #TA rsp.data; - cycle_start(); - cycle_end(); - bus.p_data <= #TA '0; - endtask - - /// Receive a request. - task recv_req (output req_t req); - bus.q_ready <= #TA 1; - cycle_start(); - while (bus.q_valid != 1) begin cycle_end(); cycle_start(); end - req = new; - req.addr = bus.q_addr; - req.write = bus.q_write; - req.amo = bus.q_amo; - req.data = bus.q_data; - req.strb = bus.q_strb; - req.user = bus.q_user; - cycle_end(); - bus.q_ready <= #TA 0; - endtask - - /// Receive a response. - task recv_rsp (output rsp_t rsp); - cycle_start(); - rsp = new; - rsp.data = bus.p_data; - cycle_end(); - endtask - - /// Monitor request. - task mon_req (output req_t req); - cycle_start(); - while (!(bus.q_valid && bus.q_ready)) begin cycle_end(); cycle_start(); end - req = new; - req.addr = bus.q_addr; - req.write = bus.q_write; - req.amo = bus.q_amo; - req.data = bus.q_data; - req.strb = bus.q_strb; - req.user = bus.q_user; - cycle_end(); - endtask - - /// Monitor response. - task mon_rsp (output rsp_t rsp); - cycle_start(); - rsp = new; - rsp.data = bus.p_data; - cycle_end(); - endtask - - endclass - -// Super classs for random mem drivers. - virtual class rand_mem #( - // mem interface parameters - parameter int AW = 32, - parameter int DW = 32, - parameter type user_t = logic, - // Stimuli application and test time - parameter time TA = 0ps, - parameter time TT = 0ps - ); - - typedef mem_test::mem_driver #( - // mem bus interface paramaters; - .AW ( AW ), - .DW ( DW ), - .user_t ( user_t ), - // Stimuli application and test time - .TA ( TA ), - .TT ( TT ) - ) mem_driver_t; - - mem_driver_t drv; - - typedef mem_driver_t::req_t req_t; - typedef mem_driver_t::rsp_t rsp_t; - - function new(virtual MEM_BUS_DV #( - .ADDR_WIDTH (AW), - .DATA_WIDTH (DW), - .user_t (user_t) - ) bus); - this.drv = new (bus); - endfunction - - task automatic rand_wait(input int unsigned min, input int unsigned max); - int unsigned rand_success, cycles; - rand_success = std::randomize(cycles) with { - cycles >= min; - cycles <= max; - // Weigh the distribution so that the minimum cycle time is the common - // case. - cycles dist {min := 10, [min:max] := 1}; - }; - assert (rand_success) else $error("Failed to randomize wait cycles!"); - repeat (cycles) @(posedge this.drv.bus.clk_i); - endtask - - endclass - - /// Generate random requests as a master device. - class rand_mem_master #( - // mem interface parameters - parameter int AW = 32, - parameter int DW = 32, - parameter type user_t = logic, - // Stimuli application and test time - parameter time TA = 0ps, - parameter time TT = 0ps, - parameter int unsigned REQ_MIN_WAIT_CYCLES = 1, - parameter int unsigned REQ_MAX_WAIT_CYCLES = 20 - ) extends rand_mem #(.AW(AW), .DW(DW), .user_t(user_t), .TA(TA), .TT(TT)); - - /// Reset the driver. - task reset(); - drv.reset_master(); - endtask - - /// Constructor. - function new(virtual MEM_BUS_DV #( - .ADDR_WIDTH (AW), - .DATA_WIDTH (DW), - .user_t (user_t) - ) bus); - super.new(bus); - endfunction - - task run(input int n); - repeat (n) begin - automatic mem_driver_t::req_t r = new; - assert(r.randomize()); - rand_wait(REQ_MIN_WAIT_CYCLES, REQ_MAX_WAIT_CYCLES); - this.drv.send_req(r); - end - endtask - endclass - - class rand_mem_slave #( - // mem interface parameters - parameter int AW = 32, - parameter int DW = 32, - parameter type user_t = logic, - parameter int unsigned RespLatency = 1, - // Stimuli application and test time - parameter time TA = 0ps, - parameter time TT = 0ps, - parameter int unsigned REQ_MIN_WAIT_CYCLES = 0, - parameter int unsigned REQ_MAX_WAIT_CYCLES = 10 - ) extends rand_mem #(.AW(AW), .DW(DW), .user_t (user_t), .TA(TA), .TT(TT)); - - mailbox req_mbx = new(); - - /// Reset the driver. - task reset(); - drv.reset_slave(); - endtask - - task run(); - fork - recv_requests(); - send_responses(); - join - endtask - - /// Constructor. - function new(virtual MEM_BUS_DV #( - .ADDR_WIDTH (AW), - .DATA_WIDTH (DW), - .user_t (user_t) - ) bus); - super.new(bus); - endfunction - - task recv_requests(); - forever begin - automatic mem_driver_t::req_t req; - rand_wait(REQ_MIN_WAIT_CYCLES, REQ_MAX_WAIT_CYCLES); - this.drv.recv_req(req); - req_mbx.put(req); - end - endtask - - task send_responses(); - automatic mem_driver_t::rsp_t rsp = new; - automatic mem_driver_t::req_t req; - forever begin - req_mbx.get(req); - assert(rsp.randomize()); - repeat (RespLatency-1) @(posedge this.drv.bus.clk_i); - this.drv.send_rsp(rsp); - end - endtask - endclass - - class mem_monitor #( - // mem interface parameters - parameter int AW = 32, - parameter int DW = 32, - parameter type user_t = logic, - parameter int unsigned RespLatency = 1, - // Stimuli application and test time - parameter time TA = 0ps, - parameter time TT = 0ps - ) extends rand_mem #(.AW(AW), .DW(DW), .user_t (user_t), .TA(TA), .TT(TT)); - - mailbox req_mbx = new, rsp_mbx = new; - typedef mem_driver_t::req_t req_t; - typedef mem_driver_t::rsp_t rsp_t; - - /// Constructor. - function new(virtual MEM_BUS_DV #( - .ADDR_WIDTH (AW), - .DATA_WIDTH (DW), - .user_t (user_t) - ) bus); - super.new(bus); - endfunction - - // mem Monitor. - task monitor; - forever begin - automatic mem_driver_t::req_t req; - this.drv.mon_req(req); - req_mbx.put(req); - fork - begin - automatic mem_driver_t::rsp_t rsp; - repeat (RespLatency-1) @(posedge this.drv.bus.clk_i); - this.drv.mon_rsp(rsp); - rsp_mbx.put(rsp); - end - join_none - end - endtask - endclass -endpackage diff --git a/hw/ip/mem_interface/src/mem_wide_narrow_mux.sv b/hw/ip/mem_interface/src/mem_wide_narrow_mux.sv index 716393c8..42fdc0ff 100644 --- a/hw/ip/mem_interface/src/mem_wide_narrow_mux.sv +++ b/hw/ip/mem_interface/src/mem_wide_narrow_mux.sv @@ -125,84 +125,3 @@ module mem_wide_narrow_mux #( (in_wide_req_i.q.data == q_data) && (in_wide_req_i.q.strb == q_strb)) endmodule - -`include "mem_interface/typedef.svh" -`include "mem_interface/assign.svh" - -/// Interface wrapper. -module mem_wide_narrow_mux_intf #( - /// Address width of wide and narrow channel. - parameter int unsigned AddrWidth = 0, - /// Width of narrow data. - parameter int unsigned NarrowDataWidth = 0, - /// Address width of wide channel. - parameter int unsigned WideDataWidth = 0, - /// User type of `mem` channel. - parameter type user_t = logic, - /// Latency of upstream memory port. - parameter int unsigned MemoryLatency = 1, - /// Derived. *Do not override* - /// Number of narrow inputs. - parameter int unsigned NrPorts = WideDataWidth / NarrowDataWidth -) ( - input logic clk_i, - input logic rst_ni, - // Inputs - /// Narrow side. - MEM_BUS in_narrow [NrPorts], - MEM_BUS in_wide, - // Output - MEM_BUS out [NrPorts], - /// `0`: Use narrow port, `1`: Use wide port - input logic sel_wide_i -); - - typedef logic [AddrWidth-1:0] addr_t; - typedef logic [NarrowDataWidth-1:0] narrow_data_t; - typedef logic [NarrowDataWidth/8-1:0] narrow_strb_t; - typedef logic [WideDataWidth-1:0] wide_data_t; - typedef logic [WideDataWidth/8-1:0] wide_strb_t; - - `MEM_TYPEDEF_ALL(mem_narrow, addr_t, narrow_data_t, narrow_strb_t, user_t) - `MEM_TYPEDEF_ALL(mem_wide, addr_t, wide_data_t, wide_strb_t, user_t) - - mem_narrow_req_t [NrPorts-1:0] in_narrow_req; - mem_narrow_rsp_t [NrPorts-1:0] in_narrow_rsp; - mem_wide_req_t in_wide_req; - mem_wide_rsp_t in_wide_rsp; - - mem_narrow_req_t [NrPorts-1:0] out_req; - mem_narrow_rsp_t [NrPorts-1:0] out_rsp; - - mem_wide_narrow_mux #( - .NarrowDataWidth (NarrowDataWidth), - .WideDataWidth (WideDataWidth), - .NrPorts (NrPorts), - .MemoryLatency (MemoryLatency), - .mem_narrow_req_t (mem_narrow_req_t), - .mem_narrow_rsp_t (mem_narrow_rsp_t), - .mem_wide_req_t (mem_wide_req_t), - .mem_wide_rsp_t (mem_wide_rsp_t) - ) i_mem_wide_narrow_mux ( - .clk_i (clk_i), - .rst_ni (rst_ni), - .in_narrow_req_i (in_narrow_req), - .in_narrow_rsp_o (in_narrow_rsp), - .in_wide_req_i (in_wide_req), - .in_wide_rsp_o (in_wide_rsp), - .out_req_o (out_req), - .out_rsp_i (out_rsp), - .sel_wide_i (sel_wide_i) - ); - - for (genvar i = 0; i < NrPorts; i++) begin : gen_interface_assign - `MEM_ASSIGN_TO_REQ(in_narrow_req[i], in_narrow[i]) - `MEM_ASSIGN_FROM_RESP(in_narrow[i], in_narrow_rsp[i]) - `MEM_ASSIGN_FROM_REQ(out[i], out_req[i]) - `MEM_ASSIGN_TO_RESP(out_rsp[i], out[i]) - end - - `MEM_ASSIGN_TO_REQ(in_wide_req, in_wide) - `MEM_ASSIGN_FROM_RESP(in_wide, in_wide_rsp) - -endmodule diff --git a/hw/ip/spatz/src/reorder_buffer.sv b/hw/ip/spatz/src/reorder_buffer.sv index 04795908..86eded87 100644 --- a/hw/ip/spatz/src/reorder_buffer.sv +++ b/hw/ip/spatz/src/reorder_buffer.sv @@ -15,7 +15,7 @@ module reorder_buffer parameter int unsigned NumWords = 0, parameter bit FallThrough = 1'b0, // Dependant parameters. Do not change! - parameter IdWidth = idx_width(NumWords), + parameter int unsigned IdWidth = idx_width(NumWords), parameter type data_t = logic [DataWidth-1:0], parameter type id_t = logic [IdWidth-1:0] ) ( diff --git a/hw/ip/spatz/src/spatz.sv b/hw/ip/spatz/src/spatz.sv index 72ecb4c3..8e0720c9 100644 --- a/hw/ip/spatz/src/spatz.sv +++ b/hw/ip/spatz/src/spatz.sv @@ -66,8 +66,8 @@ module spatz import spatz_pkg::*; import rvv_pkg::*; import fpnew_pkg::*; #( //////////////// // Number of ports of the vector register file - localparam NrWritePorts = 3; - localparam NrReadPorts = 6; + localparam int unsigned NrWritePorts = 3; + localparam int unsigned NrReadPorts = 6; ///////////// // Signals // diff --git a/hw/ip/spatz/src/spatz_controller.sv b/hw/ip/spatz/src/spatz_controller.sv index 49ee3013..ed1936db 100644 --- a/hw/ip/spatz/src/spatz_controller.sv +++ b/hw/ip/spatz/src/spatz_controller.sv @@ -219,10 +219,11 @@ module spatz_controller //////////////// // Which instruction is reading and writing to each vector register? - struct packed { + typedef struct packed { spatz_id_t id; logic valid; - } [NRVREG-1:0] read_table_d, read_table_q, write_table_d, write_table_q; + } [NRVREG-1:0] table_t; + table_t read_table_d, read_table_q, write_table_d, write_table_q; `FF(read_table_q, read_table_d, '{default: '0}) `FF(write_table_q, write_table_d, '{default: '0}) @@ -500,6 +501,7 @@ module spatz_controller issue_rsp_o.accept = 1'b0; end end // SLD + default:; endcase // Operation type // The decoding resulted in an illegal instruction end else if (decoder_rsp_valid && decoder_rsp.instr_illegal) begin diff --git a/hw/ip/spatz/src/spatz_fpu_sequencer.sv b/hw/ip/spatz/src/spatz_fpu_sequencer.sv index 4cf812b2..d1652645 100644 --- a/hw/ip/spatz/src/spatz_fpu_sequencer.sv +++ b/hw/ip/spatz/src/spatz_fpu_sequencer.sv @@ -158,12 +158,13 @@ module spatz_fpu_sequencer // Instruction decoder // /////////////////////////// - enum logic [1:0] { + typedef enum logic [1:0] { Byte = 2'b00, HalfWord = 2'b01, Word = 2'b10, Double = 2'b11 - } ls_size; + } ls_size_t; + ls_size_t ls_size; always_comb begin // We are not reading any operands @@ -380,10 +381,11 @@ module spatz_fpu_sequencer riscv_instr::FLD: begin use_fd = 1'b1; casez (issue_req_i.data_op) - riscv_instr::FLB: ls_size = Byte; - riscv_instr::FLH: ls_size = HalfWord; - riscv_instr::FLW: ls_size = Word; + riscv_instr::FLB: ls_size = Byte; + riscv_instr::FLH: ls_size = HalfWord; + riscv_instr::FLW: ls_size = Word; riscv_instr::FLD: if (RVD) ls_size = Double; + default:; endcase is_load = 1'b1; illegal_inst = !RVD && issue_req_i.data_op inside {riscv_instr::FLD}; @@ -394,10 +396,11 @@ module spatz_fpu_sequencer riscv_instr::FSD: begin use_fs2 = 1'b1; casez (issue_req_i.data_op) - riscv_instr::FSB: ls_size = Byte; - riscv_instr::FSH: ls_size = HalfWord; - riscv_instr::FSW: ls_size = Word; + riscv_instr::FSB: ls_size = Byte; + riscv_instr::FSH: ls_size = HalfWord; + riscv_instr::FSW: ls_size = Word; riscv_instr::FSD: if (RVD) ls_size = Double; + default:; endcase is_store = 1'b1; illegal_inst = !RVD && issue_req_i.data_op inside {riscv_instr::FSD}; diff --git a/hw/ip/spatz/src/spatz_ipu.sv b/hw/ip/spatz/src/spatz_ipu.sv index 32acb04f..9d6f6485 100644 --- a/hw/ip/spatz/src/spatz_ipu.sv +++ b/hw/ip/spatz/src/spatz_ipu.sv @@ -108,13 +108,15 @@ module spatz_ipu import spatz_pkg::*; import rvv_pkg::vew_e; #( if (MAXEW == rvv_pkg::EW_32) begin: gen_32b_ipu - struct packed { + typedef struct packed { + logic [1:0][7:0] ew8; + logic [15:0] ew16; + logic [31:0] ew32; + } input_ops_t; + + typedef struct packed { // Input operands - struct packed { - logic [1:0][7:0] ew8; - logic [15:0] ew16; - logic [31:0] ew32; - } [2:0] ops; + input_ops_t [2:0] ops; // Input carry logic [1:0] ew8_carry; logic ew16_carry; @@ -123,21 +125,25 @@ module spatz_ipu import spatz_pkg::*; import rvv_pkg::vew_e; #( logic [1:0] ew8_valid; logic ew16_valid; logic ew32_valid; - } lane_signal_inp; + } lane_signal_inp_t; + + lane_signal_inp_t lane_signal_inp; // SIMD output signals - struct packed { + typedef struct packed { // Results logic [1:0][7:0] ew8_res; logic [15:0] ew16_res; logic [31:0] ew32_res; - } lane_signal_res; + } lane_signal_res_t; + lane_signal_res_t lane_signal_res; - struct packed { + typedef struct packed { logic [1:0] ew8_valid; logic ew16_valid; logic ew32_valid; - } lane_signal_res_valid; + } lane_signal_res_valid_t; + lane_signal_res_valid_t lane_signal_res_valid; ///////////////// // Distributor // @@ -310,15 +316,16 @@ module spatz_ipu import spatz_pkg::*; import rvv_pkg::vew_e; #( ); end: gen_32b_ipu else if (MAXEW == rvv_pkg::EW_64) begin: gen_64b_ipu - - struct packed { + typedef struct packed { + logic [3:0][7:0] ew8; + logic [1:0][15:0] ew16; + logic [31:0] ew32; + logic [63:0] ew64; + } input_ops_t; + + typedef struct packed { // Input operands - struct packed { - logic [3:0][7:0] ew8; - logic [1:0][15:0] ew16; - logic [31:0] ew32; - logic [63:0] ew64; - } [2:0] ops; + input_ops_t [2:0] ops; // Input carry logic [3:0] ew8_carry; logic [1:0] ew16_carry; @@ -329,23 +336,26 @@ module spatz_ipu import spatz_pkg::*; import rvv_pkg::vew_e; #( logic [1:0] ew16_valid; logic ew32_valid; logic ew64_valid; - } lane_signal_inp; + } lane_signal_inp_t; + lane_signal_inp_t lane_signal_inp; // SIMD output signals - struct packed { + typedef struct packed { // Results logic [3:0][7:0] ew8_res; logic [1:0][15:0] ew16_res; logic [31:0] ew32_res; logic [63:0] ew64_res; - } lane_signal_res; + } lane_signal_res_t; + lane_signal_res_t lane_signal_res; - struct packed { + typedef struct packed { logic [3:0] ew8_valid; logic [1:0] ew16_valid; logic ew32_valid; logic ew64_valid; - } lane_signal_res_valid; + } lane_signal_res_valid_t; + lane_signal_res_valid_t lane_signal_res_valid; ///////////////// // Distributor // diff --git a/hw/ip/spatz/src/spatz_serdiv.sv b/hw/ip/spatz/src/spatz_serdiv.sv index ec63241d..722c874c 100644 --- a/hw/ip/spatz/src/spatz_serdiv.sv +++ b/hw/ip/spatz/src/spatz_serdiv.sv @@ -10,7 +10,7 @@ // Based on Ariane Multiply Divide module spatz_serdiv #( - parameter WIDTH = 64, + parameter int unsigned WIDTH = 64, parameter int unsigned IdWidth = 5 ) ( input logic clk_i, @@ -48,9 +48,10 @@ module spatz_serdiv #( rem = 1'b1; end - enum logic [1:0] { + typedef enum logic [1:0] { IDLE, DIVIDE, FINISH - } state_d, state_q; + } state_t; + state_t state_d, state_q; logic [WIDTH-1:0] res_q, res_d; logic [WIDTH-1:0] op_a_q, op_a_d; diff --git a/hw/ip/spatz/src/spatz_simd_lane.sv b/hw/ip/spatz/src/spatz_simd_lane.sv index 4550c926..bc5c684a 100644 --- a/hw/ip/spatz/src/spatz_simd_lane.sv +++ b/hw/ip/spatz/src/spatz_simd_lane.sv @@ -101,8 +101,8 @@ module spatz_simd_lane import spatz_pkg::*; import rvv_pkg::vew_e; #( logic [$clog2(Width)-1:0] shift_amount; logic [Width-1:0] shift_operand; - if (Width >= 64) begin : shift_operands - always_comb begin : shift_operands + if (Width >= 64) begin : gen_shift_operands_64 + always_comb begin unique case (sew_i) rvv_pkg::EW_64: begin shift_amount = op_s1_i[5:0]; @@ -124,9 +124,9 @@ module spatz_simd_lane import spatz_pkg::*; import rvv_pkg::vew_e; #( else shift_operand = $unsigned(op_s2_i[7:0]); end endcase - end - end else if (Width >= 32) begin - always_comb begin : shift_operands + end // always_comb + end else if (Width >= 32) begin: gen_shift_operands_32 + always_comb begin unique case (sew_i) rvv_pkg::EW_32: begin shift_amount = op_s1_i[4:0]; @@ -143,9 +143,9 @@ module spatz_simd_lane import spatz_pkg::*; import rvv_pkg::vew_e; #( else shift_operand = $unsigned(op_s2_i[7:0]); end endcase - end // shift_operands - end else if (Width >= 16) begin - always_comb begin : shift_operands + end // always_comb + end else if (Width >= 16) begin: gen_shift_operands_16 + always_comb begin unique case (sew_i) rvv_pkg::EW_16: begin shift_amount = op_s1_i[3:0]; @@ -158,7 +158,7 @@ module spatz_simd_lane import spatz_pkg::*; import rvv_pkg::vew_e; #( end endcase end // shift_operands - end else begin + end else begin: gen_shift_operands_8 always_comb begin shift_amount = op_s1_i[2:0]; shift_operand = op_s2_i[7:0]; diff --git a/hw/ip/spatz/src/spatz_vfu.sv b/hw/ip/spatz/src/spatz_vfu.sv index 342fea10..3763eb5a 100644 --- a/hw/ip/spatz/src/spatz_vfu.sv +++ b/hw/ip/spatz/src/spatz_vfu.sv @@ -103,9 +103,10 @@ module spatz_vfu assign nr_elem_word = (N_FU * (1 << (MAXEW - spatz_req.vtype.vsew))) >> spatz_req.op_arith.is_narrowing; // Are we running integer or floating-point instructions? - enum logic { + typedef enum logic { VFU_RunningIPU, VFU_RunningFPU - } state_d, state_q; + } state_t; + state_t state_d, state_q; `FF(state_q, state_d, VFU_RunningFPU) // Propagate the tags through the functional units @@ -163,13 +164,14 @@ module spatz_vfu logic last_request; // Reduction state - enum logic [2:0] { + typedef enum logic [2:0] { Reduction_NormalExecution, Reduction_Wait, Reduction_Init, Reduction_Reduce, Reduction_WriteBack - } reduction_state_d, reduction_state_q; + } reduction_state_t; + reduction_state_t reduction_state_d, reduction_state_q; `FF(reduction_state_q, reduction_state_d, Reduction_NormalExecution) // Is the reduction done? @@ -242,6 +244,7 @@ module spatz_vfu stall = 1'b1; end end + default:; endcase // Finished the execution! @@ -668,6 +671,7 @@ module spatz_vfu ipu_wide_operand2[16*el +: 16] = spatz_req.op_arith.signed_vs2 ? {{8{shift_operand2[8*el+7]}}, shift_operand2[8*el +: 8]} : {8'b0, shift_operand2[8*el +: 8]}; end end + default:; endcase end: gen_ipu_widening @@ -733,7 +737,7 @@ module spatz_vfu assign ipu_result = ipu_result_q; assign ipu_result_valid = ipu_result_valid_q; assign ipu_result_tag = ipu_result_tag_q; - end: gen_pipeline_ipu else begin + end: gen_pipeline_ipu else begin: gen_no_pipeline_ipu assign ipu_in_ready = int_ipu_in_ready; assign int_ipu_operand1 = ipu_wide_operand1; assign int_ipu_operand2 = ipu_wide_operand2; @@ -824,19 +828,15 @@ module spatz_vfu fpu_vectorial_op = FLEN > 32; end EW_16: begin - fpu_src_fmt = spatz_req.op_arith.is_narrowing || spatz_req.op_arith.widen_vs1 || spatz_req.op_arith.widen_vs2 ? fpnew_pkg::FP32 : - spatz_req.fm.src ? fpnew_pkg::FP16ALT : fpnew_pkg::FP16; - fpu_dst_fmt = spatz_req.op_arith.widen_vs1 || spatz_req.op_arith.widen_vs2 || spatz_req.op == VSDOTP ? fpnew_pkg::FP32 : - spatz_req.fm.dst ? fpnew_pkg::FP16ALT : fpnew_pkg::FP16; - fpu_int_fmt = spatz_req.op_arith.is_narrowing && spatz_req.op inside {VI2F, VU2F} ? fpnew_pkg::INT32 : fpnew_pkg::INT16; + fpu_src_fmt = spatz_req.op_arith.is_narrowing || spatz_req.op_arith.widen_vs1 || spatz_req.op_arith.widen_vs2 ? fpnew_pkg::FP32 : (spatz_req.fm.src ? fpnew_pkg::FP16ALT : fpnew_pkg::FP16); + fpu_dst_fmt = spatz_req.op_arith.widen_vs1 || spatz_req.op_arith.widen_vs2 || spatz_req.op == VSDOTP ? fpnew_pkg::FP32 : (spatz_req.fm.dst ? fpnew_pkg::FP16ALT : fpnew_pkg::FP16); + fpu_int_fmt = spatz_req.op_arith.is_narrowing && spatz_req.op inside {VI2F, VU2F} ? fpnew_pkg::INT32 : fpnew_pkg::INT16; fpu_vectorial_op = 1'b1; end EW_8: begin - fpu_src_fmt = spatz_req.op_arith.is_narrowing || spatz_req.op_arith.widen_vs1 || spatz_req.op_arith.widen_vs2 ? spatz_req.fm.src ? fpnew_pkg::FP16ALT : fpnew_pkg::FP16 : - spatz_req.fm.src ? fpnew_pkg::FP8ALT : fpnew_pkg::FP8; - fpu_dst_fmt = spatz_req.op_arith.widen_vs1 || spatz_req.op_arith.widen_vs2 || spatz_req.op == VSDOTP ? spatz_req.fm.dst ? fpnew_pkg::FP16ALT : fpnew_pkg::FP16 : - spatz_req.fm.dst ? fpnew_pkg::FP8ALT : fpnew_pkg::FP8; - fpu_int_fmt = spatz_req.op_arith.is_narrowing && spatz_req.op inside {VI2F, VU2F} ? fpnew_pkg::INT16 : fpnew_pkg::INT8; + fpu_src_fmt = spatz_req.op_arith.is_narrowing || spatz_req.op_arith.widen_vs1 || spatz_req.op_arith.widen_vs2 ? (spatz_req.fm.src ? fpnew_pkg::FP16ALT : fpnew_pkg::FP16) : (spatz_req.fm.src ? fpnew_pkg::FP8ALT : fpnew_pkg::FP8); + fpu_dst_fmt = spatz_req.op_arith.widen_vs1 || spatz_req.op_arith.widen_vs2 || spatz_req.op == VSDOTP ? (spatz_req.fm.dst ? fpnew_pkg::FP16ALT : fpnew_pkg::FP16) : (spatz_req.fm.dst ? fpnew_pkg::FP8ALT : fpnew_pkg::FP8); + fpu_int_fmt = spatz_req.op_arith.is_narrowing && spatz_req.op inside {VI2F, VU2F} ? fpnew_pkg::INT16 : fpnew_pkg::INT8; fpu_vectorial_op = 1'b1; end default:; @@ -935,6 +935,7 @@ module spatz_vfu wide_operand2[16*el +: 16] = widen_fp8_to_fp16(shift_operand2[8*el +: 8]); end end + default:; endcase end: gen_widening diff --git a/hw/ip/spatz/src/spatz_vlsu.sv b/hw/ip/spatz/src/spatz_vlsu.sv index 9fff0894..62f50f54 100644 --- a/hw/ip/spatz/src/spatz_vlsu.sv +++ b/hw/ip/spatz/src/spatz_vlsu.sv @@ -11,8 +11,8 @@ module spatz_vlsu import spatz_pkg::*; import rvv_pkg::*; import cf_math_pkg::idx_width; #( - parameter NrMemPorts = 1, - parameter NrOutstandingLoads = 8, + parameter int unsigned NrMemPorts = 1, + parameter int unsigned NrOutstandingLoads = 8, // Memory request parameter type spatz_mem_req_t = logic, parameter type spatz_mem_rsp_t = logic, @@ -128,9 +128,10 @@ module spatz_vlsu // State // ///////////// - enum logic { + typedef enum logic { VLSU_RunningLoad, VLSU_RunningStore - } state_d, state_q; + } state_t; + state_t state_d, state_q; `FF(state_q, state_d, VLSU_RunningLoad) diff --git a/hw/ip/spatz/src/spatz_vsldu.sv b/hw/ip/spatz/src/spatz_vsldu.sv index 482977a9..1562708f 100644 --- a/hw/ip/spatz/src/spatz_vsldu.sv +++ b/hw/ip/spatz/src/spatz_vsldu.sv @@ -160,10 +160,11 @@ module spatz_vsldu `FF(running_q, running_d, '0) // Respond to controller if we are finished executing - enum logic { + typedef enum logic { VSLDU_RUNNING, // Running an instruction VSLDU_WAIT_WVALID // Waiting for the last wvalid to acknowledge the instruction - } state_q, state_d; + } state_t; + state_t state_q, state_d; `FF(state_q, state_d, VSLDU_RUNNING) // New instruction @@ -223,10 +224,11 @@ module spatz_vsldu logic vreg_operation_last; // FSM to decide whether we are on the first operation or not - enum logic { + typedef enum logic { VREG_IDLE, VREG_WAIT_FIRST_WRITE - } vreg_operation_first_q, vreg_operation_first_d; + } vreg_operation_first_t; + vreg_operation_first_t vreg_operation_first_q, vreg_operation_first_d; `FF(vreg_operation_first_q, vreg_operation_first_d, VREG_IDLE) always_comb begin: vsldu_vreg_counter_proc @@ -263,6 +265,7 @@ module spatz_vsldu if (vrf_req_valid_d && vrf_req_ready_d) vreg_operation_first_d = VREG_IDLE; end + default:; endcase vreg_operation_last = spatz_req_valid && !prefetch_q && (delta <= (VRFWordBWidth - vreg_counter_q[idx_width(VRFWordBWidth)-1:0])); @@ -326,7 +329,9 @@ module spatz_vsldu state_d = VSLDU_WAIT_WVALID; end end - end + end // case: VSLDU_WAIT_WVALID + + default:; endcase end: vsldu_rsp diff --git a/hw/ip/spatz/src/vregfile.sv b/hw/ip/spatz/src/vregfile.sv index 6357eb11..559777b3 100644 --- a/hw/ip/spatz/src/vregfile.sv +++ b/hw/ip/spatz/src/vregfile.sv @@ -90,7 +90,7 @@ module vregfile import spatz_pkg::*; #( // Store new data to memory /* verilator lint_off NOLATCH */ for (genvar vreg = 0; vreg < NrWords; vreg++) begin: gen_write_mem - for (genvar b = 0; b < WordWidth/8; b++) begin + for (genvar b = 0; b < WordWidth/8; b++) begin: gen_word logic clk_latch; tc_clk_and2 i_clk_and ( .clk0_i(row_clk[vreg]), @@ -107,7 +107,7 @@ module vregfile import spatz_pkg::*; #( if (clk_latch) mem[vreg][b] <= wdata_q[b*8 +: 8]; end - end + end: gen_word end: gen_write_mem /* verilator lint_on NOLATCH */ diff --git a/hw/ip/spatz_cc/src/axi_dma_perf_counters.sv b/hw/ip/spatz_cc/src/axi_dma_perf_counters.sv index 73cd7905..9afab943 100644 --- a/hw/ip/spatz_cc/src/axi_dma_perf_counters.sv +++ b/hw/ip/spatz_cc/src/axi_dma_perf_counters.sv @@ -191,7 +191,7 @@ module axi_dma_perf_counters #( if (EnablePerfCounters) begin : gen_perf_counters `FF(dma_perf_q, dma_perf_d, 0); - end else begin + end else begin: gen_no_perf_counters assign dma_perf_q = '0; end diff --git a/hw/ip/spatz_cc/src/spatz_cc.sv b/hw/ip/spatz_cc/src/spatz_cc.sv index fdc0a2ab..d5119c85 100644 --- a/hw/ip/spatz_cc/src/spatz_cc.sv +++ b/hw/ip/spatz_cc/src/spatz_cc.sv @@ -315,7 +315,7 @@ module spatz_cc .fpu_status_o (fpu_status ) ); - for (genvar p = 0; p < NumMemPortsPerSpatz; p++) begin + for (genvar p = 0; p < NumMemPortsPerSpatz; p++) begin: gen_tcdm_assignment assign tcdm_req_o[p] = '{ q : spatz_mem_req[p], q_valid: spatz_mem_req_valid[p] diff --git a/hw/system/spatz_cluster/lint/script/lint.tcl b/hw/system/spatz_cluster/lint/script/lint.tcl index aca63760..28bb0776 100644 --- a/hw/system/spatz_cluster/lint/script/lint.tcl +++ b/hw/system/spatz_cluster/lint/script/lint.tcl @@ -1,3 +1,7 @@ +# Copyright 2023 ETH Zurich and University of Bologna. +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + set PROJECT spatz_cluster_wrapper set TIMESTAMP [exec date +%Y%m%d_%H%M%S] diff --git a/hw/system/spatz_cluster/lint/sdc/func.sdc b/hw/system/spatz_cluster/lint/sdc/func.sdc index a5b1cf04..02888e01 100644 --- a/hw/system/spatz_cluster/lint/sdc/func.sdc +++ b/hw/system/spatz_cluster/lint/sdc/func.sdc @@ -1 +1,5 @@ +# Copyright 2023 ETH Zurich and University of Bologna. +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + create_clock -period 2000 -name clk [get_ports clk_i] diff --git a/hw/system/spatz_cluster/src/spatz_amo_shim.sv b/hw/system/spatz_cluster/src/spatz_amo_shim.sv index 664539f7..3aed3be1 100644 --- a/hw/system/spatz_cluster/src/spatz_amo_shim.sv +++ b/hw/system/spatz_cluster/src/spatz_amo_shim.sv @@ -14,7 +14,7 @@ /// indicate a fault to the programmer. /// LR/SC reservations are happening on `DataWidth` granularity. -module snitch_amo_shim +module spatz_amo_shim import snitch_pkg::*; import reqrsp_pkg::*; #( @@ -235,12 +235,49 @@ module snitch_amo_shim endcase end - snitch_amo_alu i_amo_alu ( - .amo_op_i (amo_op_q), - .operand_a_i (operand_a), - .operand_b_i (operand_b_q), - .result_o (amo_result) - ); + // ---------------- + // AMO ALU + // ---------------- + + logic [33:0] adder_sum; + logic [32:0] adder_operand_a, adder_operand_b; + + assign adder_sum = adder_operand_a + adder_operand_b; + /* verilator lint_off WIDTH */ + always_comb begin : amo_alu + adder_operand_a = $signed(operand_a); + adder_operand_b = $signed(operand_b_q); + + amo_result = operand_b_q; + + unique case (amo_op_q) + // the default is to output operand_b + AMOSwap:; + AMOAdd: amo_result = adder_sum[31:0]; + AMOAnd: amo_result = operand_a & operand_b_q; + AMOOr: amo_result = operand_a | operand_b_q; + AMOXor: amo_result = operand_a ^ operand_b_q; + AMOMax: begin + adder_operand_b = -$signed(operand_b_q); + amo_result = adder_sum[32] ? operand_b_q : operand_a; + end + AMOMin: begin + adder_operand_b = -$signed(operand_b_q); + amo_result = adder_sum[32] ? operand_a : operand_b_q; + end + AMOMaxu: begin + adder_operand_a = $unsigned(operand_a); + adder_operand_b = -$unsigned(operand_b_q); + amo_result = adder_sum[32] ? operand_b_q : operand_a; + end + AMOMinu: begin + adder_operand_a = $unsigned(operand_a); + adder_operand_b = -$unsigned(operand_b_q); + amo_result = adder_sum[32] ? operand_a : operand_b_q; + end + default: amo_result = '0; + endcase + end // ---------- // Assertions @@ -256,55 +293,3 @@ module snitch_amo_shim `ASSERT(ByteMaskCorrect, valid_i && !amo_i inside {AMONone} |-> wstrb_i[4*idx_d+:4] == '1) endmodule - -/// Simple ALU supporting atomic memory operations. -module snitch_amo_alu import reqrsp_pkg::*; ( - input amo_op_e amo_op_i, - input logic [31:0] operand_a_i, - input logic [31:0] operand_b_i, - output logic [31:0] result_o -); - // ---------------- - // AMO ALU - // ---------------- - logic [33:0] adder_sum; - logic [32:0] adder_operand_a, adder_operand_b; - - assign adder_sum = adder_operand_a + adder_operand_b; - /* verilator lint_off WIDTH */ - always_comb begin : amo_alu - - adder_operand_a = $signed(operand_a_i); - adder_operand_b = $signed(operand_b_i); - - result_o = operand_b_i; - - unique case (amo_op_i) - // the default is to output operand_b - AMOSwap:; - AMOAdd: result_o = adder_sum[31:0]; - AMOAnd: result_o = operand_a_i & operand_b_i; - AMOOr: result_o = operand_a_i | operand_b_i; - AMOXor: result_o = operand_a_i ^ operand_b_i; - AMOMax: begin - adder_operand_b = -$signed(operand_b_i); - result_o = adder_sum[32] ? operand_b_i : operand_a_i; - end - AMOMin: begin - adder_operand_b = -$signed(operand_b_i); - result_o = adder_sum[32] ? operand_a_i : operand_b_i; - end - AMOMaxu: begin - adder_operand_a = $unsigned(operand_a_i); - adder_operand_b = -$unsigned(operand_b_i); - result_o = adder_sum[32] ? operand_b_i : operand_a_i; - end - AMOMinu: begin - adder_operand_a = $unsigned(operand_a_i); - adder_operand_b = -$unsigned(operand_b_i); - result_o = adder_sum[32] ? operand_a_i : operand_b_i; - end - default: result_o = '0; - endcase - end -endmodule diff --git a/hw/system/spatz_cluster/src/spatz_cluster.sv b/hw/system/spatz_cluster/src/spatz_cluster.sv index ee486ee7..8126e6ec 100644 --- a/hw/system/spatz_cluster/src/spatz_cluster.sv +++ b/hw/system/spatz_cluster/src/spatz_cluster.sv @@ -606,7 +606,7 @@ module spatz_cluster data_t amo_rdata_local; // TODO(zarubaf): Share atomic units between mutltiple cuts - snitch_amo_shim #( + spatz_amo_shim #( .AddrMemWidth ( TCDMMemAddrWidth ), .DataWidth ( DataWidth ), .CoreIDWidth ( CoreIDWidth ) @@ -773,7 +773,7 @@ module spatz_cluster assign wide_axi_mst_req[SDMAMst] = axi_dma_req; assign axi_dma_res = wide_axi_mst_rsp[SDMAMst]; assign dma_events = dma_core_events; - end else begin + end else begin: gen_no_dma_connection assign axi_dma_res = '0; end end diff --git a/hw/system/spatz_cluster/test/bootrom.S b/hw/system/spatz_cluster/test/bootrom.S index 7e71a56c..726ea13a 100644 --- a/hw/system/spatz_cluster/test/bootrom.S +++ b/hw/system/spatz_cluster/test/bootrom.S @@ -1,6 +1,6 @@ -# Copyright 2020 ETH Zurich and University of Bologna. -# Solderpad Hardware License, Version 0.51, see LICENSE for details. -# SPDX-License-Identifier: SHL-0.51 +// Copyright 2020 ETH Zurich and University of Bologna. +// Solderpad Hardware License, Version 0.51, see LICENSE for details. +// SPDX-License-Identifier: SHL-0.51 #include