From 34e57f0b14021a735a686d0da974824cb94ef6d5 Mon Sep 17 00:00:00 2001 From: Luke Wren Date: Sat, 4 Dec 2021 18:52:41 +0000 Subject: [PATCH] Sketch in an AMO ALU --- hdl/arith/hazard3_alu.v | 2 +- hdl/arith/hazard3_amo_alu.v | 59 +++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 hdl/arith/hazard3_amo_alu.v diff --git a/hdl/arith/hazard3_alu.v b/hdl/arith/hazard3_alu.v index 042192d..15a9c43 100644 --- a/hdl/arith/hazard3_alu.v +++ b/hdl/arith/hazard3_alu.v @@ -2,7 +2,7 @@ * DO WHAT THE FUCK YOU WANT TO AND DON'T BLAME US PUBLIC LICENSE * * Version 3, April 2008 * * * - * Copyright (C) 2018 Luke Wren * + * Copyright (C) 2021 Luke Wren * * * * Everyone is permitted to copy and distribute verbatim or modified * * copies of this license document and accompanying software, and * diff --git a/hdl/arith/hazard3_amo_alu.v b/hdl/arith/hazard3_amo_alu.v new file mode 100644 index 0000000..689a130 --- /dev/null +++ b/hdl/arith/hazard3_amo_alu.v @@ -0,0 +1,59 @@ +/********************************************************************** + * DO WHAT THE FUCK YOU WANT TO AND DON'T BLAME US PUBLIC LICENSE * + * Version 3, April 2008 * + * * + * Copyright (C) 2021 Luke Wren * + * * + * Everyone is permitted to copy and distribute verbatim or modified * + * copies of this license document and accompanying software, and * + * changing either is allowed. * + * * + * TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION * + * * + * 0. You just DO WHAT THE FUCK YOU WANT TO. * + * 1. We're NOT RESPONSIBLE WHEN IT DOESN'T FUCKING WORK. * + * * + *********************************************************************/ + +// Separate ALU for atomic memory operations + +`default_nettype none +module hazard3_amo_alu #( +`include "hazard3_config.vh" +, +`include "hazard3_width_const.vh" +) ( + input wire [W_MEMOP-1:0] op, + input wire [W_DATA-1:0] op_rs1, // From load + input wire [W_DATA-1:0] op_rs2, // From core + output reg [W_DATA-1:0] result +); + +wire sub = op != MEMOP_AMOADD_W; +wire cmp_unsigned = op == MEMOP_AMOMINU_W || op == MEMOP_AMOMAXU_W; + +wire [W_DATA-1:0] sum = op_rs1 + (op_rs2 ^ {W_DATA{sub}}) + sub; + +wire rs1_lessthan_rs2 = + op_rs1[W_DATA-1] == op_rs2[W_DATA-1] ? sum[W_DATA-1] : + cmp_unsigned ? op_rs2[W_DATA-1] : + op_rs1[W_DATA-1] ; + +always @ (*) begin + case(op) + MEMOP_AMOADD_W : result = sum; + MEMOP_AMOXOR_W : result = op_rs1 ^ op_rs2; + MEMOP_AMOAND_W : result = op_rs1 & op_rs2; + MEMOP_AMOOR_W : result = op_rs1 | op_rs2; + MEMOP_AMOMIN_W : result = rs1_lessthan_rs2 ? op_rs1 : op_rs2; + MEMOP_AMOMAX_W : result = rs1_lessthan_rs2 ? op_rs2 : op_rs1; + MEMOP_AMOMINU_W: result = rs1_lessthan_rs2 ? op_rs1 : op_rs2; + MEMOP_AMOMAXU_W: result = rs1_lessthan_rs2 ? op_rs2 : op_rs1; + // AMOSWAP + default: result = op_rs2; + endcase +end + +endmodule + +`default_nettype wire