73 lines
2.4 KiB
Coq
73 lines
2.4 KiB
Coq
|
/**********************************************************************
|
||
|
* DO WHAT THE FUCK YOU WANT TO AND DON'T BLAME US PUBLIC LICENSE *
|
||
|
* Version 3, April 2008 *
|
||
|
* *
|
||
|
* Copyright (C) 2018 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. *
|
||
|
* *
|
||
|
*********************************************************************/
|
||
|
|
||
|
module hazard5_shift_1bit_seq #(
|
||
|
parameter W_DATA = 32,
|
||
|
parameter W_SHAMT = 5
|
||
|
) (
|
||
|
input wire clk,
|
||
|
input wire rst_n,
|
||
|
|
||
|
input wire [W_DATA-1:0] din,
|
||
|
input wire din_vld, // can be asserted at any time, we always respond
|
||
|
input wire [W_SHAMT-1:0] shamt,
|
||
|
input wire right_nleft,
|
||
|
input wire arith,
|
||
|
output wire [W_DATA-1:0] dout,
|
||
|
output wire dout_vld,
|
||
|
);
|
||
|
|
||
|
reg [W_DATA-1:0] accum;
|
||
|
reg [W_DATA-1:0] accum_next;
|
||
|
reg [W_SHAMT-1:0] shamt_remaining;
|
||
|
reg flipped;
|
||
|
|
||
|
// Handle actual shifting
|
||
|
|
||
|
wire sext = arith && accum[W_DATA - 1];
|
||
|
|
||
|
always @ (*) begin: shift_unit
|
||
|
accum_next = accum;
|
||
|
if (din_vld) begin
|
||
|
accum_next = din;
|
||
|
end else if (shamt_remaining) begin
|
||
|
if (right_nleft)
|
||
|
accum_next = {sext, accum[W_DATA-1:1]};
|
||
|
else
|
||
|
accum_next = {accum << 1};
|
||
|
end
|
||
|
end
|
||
|
|
||
|
// No reset on datapath
|
||
|
always @ (posedge clk)
|
||
|
accum <= accum_next;
|
||
|
|
||
|
always @ (posedge clk or negedge rst_n) begin
|
||
|
if (!rst_n) begin
|
||
|
shamt_remaining <= {W_SHAMT{1'b0}};
|
||
|
end else if (din_vld) begin
|
||
|
shamt_remaining <= shamt;
|
||
|
end else begin
|
||
|
shamt_remaining <= shamt_remaining - |shamt_remaining;
|
||
|
end
|
||
|
end
|
||
|
|
||
|
assign dout_vld = shamt_remaining == 0;
|
||
|
assign dout = accum;
|
||
|
|
||
|
endmodule
|