module std_mem_d1 #( parameter WIDTH = 32, parameter SIZE = 16, parameter IDX_SIZE = 4 ) ( input wire logic [IDX_SIZE-1:0] addr0, input wire logic [ WIDTH-1:0] write_data, input wire logic write_en, input wire logic clk, input wire logic reset, output logic [ WIDTH-1:0] read_data, output logic done ); logic [WIDTH-1:0] mem[SIZE-1:0]; initial begin $readmemh({"sim_data/mem.dat"}, mem); end final begin $writememh({"sim_data/mem.out"}, mem); end /* verilator lint_off WIDTH */ assign read_data = mem[addr0]; always_ff @(posedge clk) begin if (reset) done <= '0; else if (write_en) done <= '1; else done <= '0; end always_ff @(posedge clk) begin if (!reset && write_en) mem[addr0] <= write_data; end // Check for out of bounds access `ifdef VERILATOR always_comb begin if (addr0 >= SIZE) $error( "std_mem_d1: Out of bounds access\n", "addr0: %0d\n", addr0, "SIZE: %0d", SIZE ); end `endif endmodule /** * Core primitives for Calyx. * Implements core primitives used by the compiler. * * Conventions: * - All parameter names must be SNAKE_CASE and all caps. * - Port names must be snake_case, no caps. */ `default_nettype none module std_slice #( parameter IN_WIDTH = 32, parameter OUT_WIDTH = 32 ) ( input wire logic [ IN_WIDTH-1:0] in, output logic [OUT_WIDTH-1:0] out ); assign out = in[OUT_WIDTH-1:0]; `ifdef VERILATOR always_comb begin if (IN_WIDTH < OUT_WIDTH) $error( "std_slice: Input width less than output width\n", "IN_WIDTH: %0d", IN_WIDTH, "OUT_WIDTH: %0d", OUT_WIDTH ); end `endif endmodule module std_pad #( parameter IN_WIDTH = 32, parameter OUT_WIDTH = 32 ) ( input wire logic [IN_WIDTH-1:0] in, output logic [OUT_WIDTH-1:0] out ); localparam EXTEND = OUT_WIDTH - IN_WIDTH; assign out = { {EXTEND {1'b0}}, in}; `ifdef VERILATOR always_comb begin if (IN_WIDTH > OUT_WIDTH) $error( "std_pad: Output width less than input width\n", "IN_WIDTH: %0d", IN_WIDTH, "OUT_WIDTH: %0d", OUT_WIDTH ); end `endif endmodule module std_cat #( parameter LEFT_WIDTH = 32, parameter RIGHT_WIDTH = 32, parameter OUT_WIDTH = 64 ) ( input wire logic [LEFT_WIDTH-1:0] left, input wire logic [RIGHT_WIDTH-1:0] right, output logic [OUT_WIDTH-1:0] out ); assign out = {left, right}; `ifdef VERILATOR always_comb begin if (LEFT_WIDTH + RIGHT_WIDTH != OUT_WIDTH) $error( "std_cat: Output width must equal sum of input widths\n", "LEFT_WIDTH: %0d", LEFT_WIDTH, "RIGHT_WIDTH: %0d", RIGHT_WIDTH, "OUT_WIDTH: %0d", OUT_WIDTH ); end `endif endmodule module std_not #( parameter WIDTH = 32 ) ( input wire logic [WIDTH-1:0] in, output logic [WIDTH-1:0] out ); assign out = ~in; endmodule module std_and #( parameter WIDTH = 32 ) ( input wire logic [WIDTH-1:0] left, input wire logic [WIDTH-1:0] right, output logic [WIDTH-1:0] out ); assign out = left & right; endmodule module std_or #( parameter WIDTH = 32 ) ( input wire logic [WIDTH-1:0] left, input wire logic [WIDTH-1:0] right, output logic [WIDTH-1:0] out ); assign out = left | right; endmodule module std_xor #( parameter WIDTH = 32 ) ( input wire logic [WIDTH-1:0] left, input wire logic [WIDTH-1:0] right, output logic [WIDTH-1:0] out ); assign out = left ^ right; endmodule module std_sub #( parameter WIDTH = 32 ) ( input wire logic [WIDTH-1:0] left, input wire logic [WIDTH-1:0] right, output logic [WIDTH-1:0] out ); assign out = left - right; endmodule module std_gt #( parameter WIDTH = 32 ) ( input wire logic [WIDTH-1:0] left, input wire logic [WIDTH-1:0] right, output logic out ); assign out = left > right; endmodule module std_lt #( parameter WIDTH = 32 ) ( input wire logic [WIDTH-1:0] left, input wire logic [WIDTH-1:0] right, output logic out ); assign out = left < right; endmodule module std_eq #( parameter WIDTH = 32 ) ( input wire logic [WIDTH-1:0] left, input wire logic [WIDTH-1:0] right, output logic out ); assign out = left == right; endmodule module std_neq #( parameter WIDTH = 32 ) ( input wire logic [WIDTH-1:0] left, input wire logic [WIDTH-1:0] right, output logic out ); assign out = left != right; endmodule module std_ge #( parameter WIDTH = 32 ) ( input wire logic [WIDTH-1:0] left, input wire logic [WIDTH-1:0] right, output logic out ); assign out = left >= right; endmodule module std_le #( parameter WIDTH = 32 ) ( input wire logic [WIDTH-1:0] left, input wire logic [WIDTH-1:0] right, output logic out ); assign out = left <= right; endmodule module std_lsh #( parameter WIDTH = 32 ) ( input wire logic [WIDTH-1:0] left, input wire logic [WIDTH-1:0] right, output logic [WIDTH-1:0] out ); assign out = left << right; endmodule module std_rsh #( parameter WIDTH = 32 ) ( input wire logic [WIDTH-1:0] left, input wire logic [WIDTH-1:0] right, output logic [WIDTH-1:0] out ); assign out = left >> right; endmodule /// this primitive is intended to be used /// for lowering purposes (not in source programs) module std_mux #( parameter WIDTH = 32 ) ( input wire logic cond, input wire logic [WIDTH-1:0] tru, input wire logic [WIDTH-1:0] fal, output logic [WIDTH-1:0] out ); assign out = cond ? tru : fal; endmodule `default_nettype wire module undef #( parameter WIDTH = 32 ) ( output logic [WIDTH-1:0] out ); assign out = 'x; endmodule module std_const #( parameter WIDTH = 32, parameter VALUE = 32 ) ( output logic [WIDTH-1:0] out ); assign out = VALUE; endmodule module std_wire #( parameter WIDTH = 32 ) ( input logic [WIDTH-1:0] in, output logic [WIDTH-1:0] out ); assign out = in; endmodule module std_add #( parameter WIDTH = 32 ) ( input logic [WIDTH-1:0] left, input logic [WIDTH-1:0] right, output logic [WIDTH-1:0] out ); assign out = left + right; endmodule module std_reg #( parameter WIDTH = 32 ) ( input logic [WIDTH-1:0] in, input logic write_en, input logic clk, input logic reset, output logic [WIDTH-1:0] out, output logic done ); always_ff @(posedge clk) begin if (reset) begin out <= 0; done <= 0; end else if (write_en) begin out <= in; done <= 1'd1; end else done <= 1'd0; end endmodule