My Verilog skills are very poor and this is non-idiomatic Verilog, but should show how you can make a fully synchronous design for your data interfaces, in a behavioral way, not structural. It really does help to make your designs maintainable and extendable without lots of design work.
It's also got a very simplistic synchronizers for the control signals. Hopefully it helps rather than distracts.
`timescale 1ns / 1ps
module design1(
input clk,
// Shift register interface
input s_data,
input s_clock,
input s_execute,
input reset,
// Just a generic ouput signal
output reg ctrl
);
reg synced_s_data_last = 1'b0, synced_s_data = 1'b0, unsafe_s_data = 1'b0;
reg synced_s_clock_last = 1'b0, synced_s_clock = 1'b0, unsafe_s_clock = 1'b0;
reg synced_s_execute_last = 1'b0, synced_s_execute = 1'b0, unsafe_s_execute = 1'b0;
reg synced_reset = 1'b0, unsafe_reset = 1'b0;
reg [15:0] shift_reg;
reg[7:0] my_reg_5;
reg[7:0] my_reg_6;
reg[7:0] my_reg_7;
always @(posedge clk) begin
// Synchonize everyting to the fast system clock
// Note this is a very nieve implementation of a synchronizer, but should work.
synced_s_execute_last <= synced_s_execute;
synced_s_execute <= unsafe_s_execute;
unsafe_s_execute <= s_execute;
synced_s_clock_last <= synced_s_clock;
synced_s_clock <= unsafe_s_clock;
unsafe_s_clock <= s_clock;
synced_s_data_last <= synced_s_data;
synced_s_data <= unsafe_s_data;
unsafe_s_data <= s_data;
// A super-poor reset synchronizer
synced_reset <= unsafe_reset;
unsafe_reset <= reset;
end
// Move bits into the sift register and act on them
always @(posedge clk) begin
if(synced_reset) begin
// Set safe power on variables
my_reg_5 <= 8'b10101010;
my_reg_6 <= 8'b00000000;
my_reg_7 <= 8'b00000000;
shift_reg <= 16'b0000000000000000;
ctrl <= 1'b0;
end else begin
// If we have seen the rising edge on the execute signal
if(synced_s_execute_last == 1'b0 && synced_s_execute == 1'b1) begin
// Execute the command in bits 2:0
case(shift_reg[2:0])
3'b001: ctrl <= 1'b0; // Do something on command 1
3'b010: ctrl <= 1'b1; // Do something on command 2
3'b101: my_reg_5 <= shift_reg[15:8]; // Update register values
3'b110: my_reg_6 <= shift_reg[15:8];
3'b111: my_reg_7 <= shift_reg[15:8];
endcase
end
// If we have seen the rising edge on the shift register clock signal
if(synced_s_clock_last == 1'b0 && synced_s_clock == 1'b1) begin
// Shift in a new bit
shift_reg <= { shift_reg[14:0], synced_s_data};
end
end
end
endmodule