553 lines
18 KiB
Verilog
553 lines
18 KiB
Verilog
//
|
|
//
|
|
// File Name : four_module_lockstep.v
|
|
// Used on :
|
|
// Author : Ted Fried, MicroCore Labs
|
|
// Creation : 9/16/16
|
|
// Code Type : Synthesizable
|
|
//
|
|
// Description:
|
|
// ============
|
|
//
|
|
//
|
|
//
|
|
//------------------------------------------------------------------------
|
|
//
|
|
// Modification History:
|
|
// =====================
|
|
//
|
|
// Revision 1.0 9/16/16
|
|
// Initial revision
|
|
//
|
|
//
|
|
//------------------------------------------------------------------------
|
|
//
|
|
// Copyright (c) 2020 Ted Fried
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
// of this software and associated documentation files (the "Software"), to deal
|
|
// in the Software without restriction, including without limitation the rights
|
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
// copies of the Software, and to permit persons to whom the Software is
|
|
// furnished to do so, subject to the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included in all
|
|
// copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
// SOFTWARE.
|
|
//
|
|
//------------------------------------------------------------------------
|
|
|
|
`timescale 1ns/100ps
|
|
|
|
|
|
module four_module_lockstep
|
|
(
|
|
input CORE_CLK, // Core Signals
|
|
input RST_n,
|
|
|
|
|
|
input [3:0] KILL_MODE,
|
|
input [3:0] PB_SWITCH,
|
|
output [3:0] LEDS,
|
|
output [3:0] PROBE,
|
|
|
|
input UART_RX, // UART
|
|
output UART_TX,
|
|
output SPEAKER
|
|
|
|
);
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
|
|
// Internal Signals
|
|
|
|
|
|
reg proxy_wr;
|
|
reg proxy_rd;
|
|
reg [15:0] proxy_address;
|
|
reg [7:0] prody_wr_data;
|
|
wire module0_broadcast_ok;
|
|
wire module1_broadcast_ok;
|
|
wire module2_broadcast_ok;
|
|
wire module3_broadcast_ok;
|
|
wire timer_wr_strobe;
|
|
wire uart_wr_strobe;
|
|
wire uart_rd_strobe;
|
|
wire core_clk_int;
|
|
wire module0_sync;
|
|
wire module1_sync;
|
|
wire module2_sync;
|
|
wire module3_sync;
|
|
wire interrupt2;
|
|
wire interrupt3;
|
|
wire [7:0] module0_strobe;
|
|
wire [7:0] module1_strobe;
|
|
wire [7:0] module2_strobe;
|
|
wire [7:0] module3_strobe;
|
|
wire [7:0] top_strobe;
|
|
wire [15:0] module0_address;
|
|
wire [15:0] module1_address;
|
|
wire [15:0] module2_address;
|
|
wire [15:0] module3_address;
|
|
wire [15:0] top_address;
|
|
wire [7:0] module0_data;
|
|
wire [7:0] module1_data;
|
|
wire [7:0] module2_data;
|
|
wire [7:0] module3_data;
|
|
wire [7:0] top_data;
|
|
wire [7:0] proxy_rd_data_int;
|
|
wire [7:0] timer_dataout;
|
|
wire [7:0] uart_dataout;
|
|
wire [15:0] module0_ip;
|
|
wire [15:0] module1_ip;
|
|
wire [15:0] module2_ip;
|
|
wire [15:0] module3_ip;
|
|
|
|
|
|
reg [3:0] pbsw_d1;
|
|
reg [3:0] pbsw_d2;
|
|
reg [3:0] pbsw_d3;
|
|
reg [3:0] pbsw_d4;
|
|
reg [3:0] pbsw_d5;
|
|
|
|
reg rst_n_d1;
|
|
reg rst_n_d2;
|
|
reg rst_n_d3;
|
|
reg rst_n_d4;
|
|
|
|
reg [3:0] kmode_d1;
|
|
reg [3:0] kmode_d2;
|
|
reg [3:0] kmode_d3;
|
|
reg [3:0] kmode_d4;
|
|
|
|
reg kill0;
|
|
reg kill1;
|
|
reg kill2;
|
|
reg kill3;
|
|
|
|
wire core_clk_locked;
|
|
|
|
reg speaker_int_d1;
|
|
reg speaker_int_d2;
|
|
reg speaker_int_d3;
|
|
wire speaker_int;
|
|
|
|
|
|
assign core_clk_int = CORE_CLK;
|
|
|
|
|
|
|
|
assign LEDS[3] = ~module3_broadcast_ok;
|
|
assign LEDS[2] = ~module2_broadcast_ok;
|
|
assign LEDS[1] = ~module1_broadcast_ok;
|
|
assign LEDS[0] = ~module0_broadcast_ok;
|
|
|
|
assign PROBE[3] = ~module3_broadcast_ok;
|
|
assign PROBE[2] = ~module2_broadcast_ok;
|
|
assign PROBE[1] = ~module1_broadcast_ok;
|
|
assign PROBE[0] = ~module0_broadcast_ok;
|
|
|
|
assign SPEAKER = speaker_int_d3;
|
|
|
|
|
|
always @(posedge core_clk_int)
|
|
begin : BUTTON_DEBOUNCE
|
|
|
|
speaker_int_d1 <= speaker_int;
|
|
speaker_int_d2 <= speaker_int_d1;
|
|
speaker_int_d3 <= speaker_int_d2;
|
|
|
|
rst_n_d1 <= RST_n;
|
|
rst_n_d2 <= rst_n_d1;
|
|
rst_n_d3 <= rst_n_d2;
|
|
rst_n_d4 <= rst_n_d3;
|
|
|
|
pbsw_d1 <= PB_SWITCH;
|
|
pbsw_d2 <= pbsw_d1;
|
|
pbsw_d3 <= pbsw_d2;
|
|
pbsw_d4 <= pbsw_d3;
|
|
pbsw_d5 <= pbsw_d4;
|
|
|
|
kmode_d1 <= KILL_MODE;
|
|
kmode_d2 <= kmode_d1;
|
|
kmode_d3 <= kmode_d2;
|
|
kmode_d4 <= kmode_d3;
|
|
|
|
if (pbsw_d5[3]==1'b1 && pbsw_d4[3]==1'b1 && pbsw_d3[3]==1'b1 && pbsw_d2[3]==1'b1) begin kill3 <= 1'b1; end
|
|
else if (pbsw_d5[3]==1'b0 && pbsw_d4[3]==1'b0 && pbsw_d3[3]==1'b0 && pbsw_d2[3]==1'b0) begin kill3 <= 1'b0; end
|
|
|
|
if (pbsw_d5[2]==1'b1 && pbsw_d4[2]==1'b1 && pbsw_d3[2]==1'b1 && pbsw_d2[2]==1'b1) begin kill2 <= 1'b1; end
|
|
else if (pbsw_d5[2]==1'b0 && pbsw_d4[2]==1'b0 && pbsw_d3[2]==1'b0 && pbsw_d2[2]==1'b0) begin kill2 <= 1'b0; end
|
|
|
|
if (pbsw_d5[1]==1'b1 && pbsw_d4[1]==1'b1 && pbsw_d3[1]==1'b1 && pbsw_d2[1]==1'b1) begin kill1 <= 1'b1; end
|
|
else if (pbsw_d5[1]==1'b0 && pbsw_d4[1]==1'b0 && pbsw_d3[1]==1'b0 && pbsw_d2[1]==1'b0) begin kill1 <= 1'b0; end
|
|
|
|
if (pbsw_d5[0]==1'b1 && pbsw_d4[0]==1'b1 && pbsw_d3[0]==1'b1 && pbsw_d2[0]==1'b1) begin kill0 <= 1'b1; end
|
|
else if (pbsw_d5[0]==1'b0 && pbsw_d4[0]==1'b0 && pbsw_d3[0]==1'b0 && pbsw_d2[0]==1'b0) begin kill0 <= 1'b0; end
|
|
|
|
|
|
|
|
end // BIU Controller
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
//
|
|
// Lockstep Modules
|
|
//
|
|
//------------------------------------------------------------------------
|
|
|
|
module_block MODULE0
|
|
(
|
|
.CORE_CLK (core_clk_int),
|
|
.RST_n (rst_n_d4),
|
|
.KILL (kill0),
|
|
.KILL_MODE (kmode_d4),
|
|
.MODULE_ID (2'h0),
|
|
|
|
.BROADCAST_OK (module0_broadcast_ok),
|
|
.BROADCAST_STROBE (module0_strobe),
|
|
.BROADCAST_ADDRESS (module0_address),
|
|
.BROADCAST_DATA (module0_data),
|
|
.BROADCAST_IP (module0_ip),
|
|
.BROADCAST_SYNC (module0_sync),
|
|
.BROADCAST_IDSBL (module0_idsbl),
|
|
|
|
.BROADCAST_OK_IN0 (module1_broadcast_ok),
|
|
.BROADCAST_STROBE_IN0 (module1_strobe),
|
|
.BROADCAST_ADDRESS_IN0 (module1_address),
|
|
.BROADCAST_DATA_IN0 (module1_data),
|
|
.BROADCAST_IP_IN0 (module1_ip),
|
|
.BROADCAST_SYNC_IN0 (module1_sync),
|
|
.BROADCAST_IDSBL_IN0 (module1_idsbl),
|
|
|
|
.BROADCAST_OK_IN1 (module2_broadcast_ok),
|
|
.BROADCAST_STROBE_IN1 (module2_strobe),
|
|
.BROADCAST_ADDRESS_IN1 (module2_address),
|
|
.BROADCAST_DATA_IN1 (module2_data),
|
|
.BROADCAST_IP_IN1 (module2_ip),
|
|
.BROADCAST_SYNC_IN1 (module2_sync),
|
|
.BROADCAST_IDSBL_IN1 (module2_idsbl),
|
|
|
|
.BROADCAST_OK_IN2 (module3_broadcast_ok),
|
|
.BROADCAST_STROBE_IN2 (module3_strobe),
|
|
.BROADCAST_ADDRESS_IN2 (module3_address),
|
|
.BROADCAST_DATA_IN2 (module3_data),
|
|
.BROADCAST_IP_IN2 (module3_ip),
|
|
.BROADCAST_SYNC_IN2 (module3_sync),
|
|
.BROADCAST_IDSBL_IN2 (module3_idsbl),
|
|
|
|
. INT2 (interrupt2),
|
|
. INT3 (interrupt3),
|
|
|
|
.PROXY_RD_DATA (proxy_rd_data_int)
|
|
|
|
);
|
|
|
|
|
|
module_block MODULE1
|
|
(
|
|
.CORE_CLK (core_clk_int),
|
|
.RST_n (rst_n_d4),
|
|
.KILL (kill1),
|
|
.KILL_MODE (kmode_d4),
|
|
.MODULE_ID (2'h1),
|
|
|
|
.BROADCAST_OK (module1_broadcast_ok),
|
|
.BROADCAST_STROBE (module1_strobe),
|
|
.BROADCAST_ADDRESS (module1_address),
|
|
.BROADCAST_DATA (module1_data),
|
|
.BROADCAST_IP (module1_ip),
|
|
.BROADCAST_SYNC (module1_sync),
|
|
.BROADCAST_IDSBL (module1_idsbl),
|
|
|
|
.BROADCAST_OK_IN0 (module2_broadcast_ok),
|
|
.BROADCAST_STROBE_IN0 (module2_strobe),
|
|
.BROADCAST_ADDRESS_IN0 (module2_address),
|
|
.BROADCAST_DATA_IN0 (module2_data),
|
|
.BROADCAST_IP_IN0 (module2_ip),
|
|
.BROADCAST_SYNC_IN0 (module2_sync),
|
|
.BROADCAST_IDSBL_IN0 (module2_idsbl),
|
|
|
|
.BROADCAST_OK_IN1 (module3_broadcast_ok),
|
|
.BROADCAST_STROBE_IN1 (module3_strobe),
|
|
.BROADCAST_ADDRESS_IN1 (module3_address),
|
|
.BROADCAST_DATA_IN1 (module3_data),
|
|
.BROADCAST_IP_IN1 (module3_ip),
|
|
.BROADCAST_SYNC_IN1 (module3_sync),
|
|
.BROADCAST_IDSBL_IN1 (module3_idsbl),
|
|
|
|
.BROADCAST_OK_IN2 (module0_broadcast_ok),
|
|
.BROADCAST_STROBE_IN2 (module0_strobe),
|
|
.BROADCAST_ADDRESS_IN2 (module0_address),
|
|
.BROADCAST_DATA_IN2 (module0_data),
|
|
.BROADCAST_IP_IN2 (module0_ip),
|
|
.BROADCAST_SYNC_IN2 (module0_sync),
|
|
.BROADCAST_IDSBL_IN2 (module0_idsbl),
|
|
|
|
. INT2 (interrupt2),
|
|
. INT3 (interrupt3),
|
|
|
|
.PROXY_RD_DATA (proxy_rd_data_int)
|
|
|
|
);
|
|
|
|
|
|
module_block MODULE2
|
|
(
|
|
.CORE_CLK (core_clk_int),
|
|
.RST_n (rst_n_d4),
|
|
.KILL (kill2),
|
|
.KILL_MODE (kmode_d4),
|
|
.MODULE_ID (2'h2),
|
|
|
|
.BROADCAST_OK (module2_broadcast_ok),
|
|
.BROADCAST_STROBE (module2_strobe),
|
|
.BROADCAST_ADDRESS (module2_address),
|
|
.BROADCAST_DATA (module2_data),
|
|
.BROADCAST_IP (module2_ip),
|
|
.BROADCAST_SYNC (module2_sync),
|
|
.BROADCAST_IDSBL (module2_idsbl),
|
|
|
|
.BROADCAST_OK_IN0 (module3_broadcast_ok),
|
|
.BROADCAST_STROBE_IN0 (module3_strobe),
|
|
.BROADCAST_ADDRESS_IN0 (module3_address),
|
|
.BROADCAST_DATA_IN0 (module3_data),
|
|
.BROADCAST_IP_IN0 (module3_ip),
|
|
.BROADCAST_SYNC_IN0 (module3_sync),
|
|
.BROADCAST_IDSBL_IN0 (module3_idsbl),
|
|
|
|
.BROADCAST_OK_IN1 (module0_broadcast_ok),
|
|
.BROADCAST_STROBE_IN1 (module0_strobe),
|
|
.BROADCAST_ADDRESS_IN1 (module0_address),
|
|
.BROADCAST_DATA_IN1 (module0_data),
|
|
.BROADCAST_IP_IN1 (module0_ip),
|
|
.BROADCAST_SYNC_IN1 (module0_sync),
|
|
.BROADCAST_IDSBL_IN1 (module0_idsbl),
|
|
|
|
.BROADCAST_OK_IN2 (module1_broadcast_ok),
|
|
.BROADCAST_STROBE_IN2 (module1_strobe),
|
|
.BROADCAST_ADDRESS_IN2 (module1_address),
|
|
.BROADCAST_DATA_IN2 (module1_data),
|
|
.BROADCAST_IP_IN2 (module1_ip),
|
|
.BROADCAST_SYNC_IN2 (module1_sync),
|
|
.BROADCAST_IDSBL_IN2 (module1_idsbl),
|
|
|
|
. INT2 (interrupt2),
|
|
. INT3 (interrupt3),
|
|
|
|
.PROXY_RD_DATA (proxy_rd_data_int)
|
|
|
|
);
|
|
|
|
|
|
module_block MODULE3
|
|
(
|
|
.CORE_CLK (core_clk_int),
|
|
.RST_n (rst_n_d4),
|
|
.KILL (kill3),
|
|
.KILL_MODE (kmode_d4),
|
|
.MODULE_ID (2'h3),
|
|
|
|
.BROADCAST_OK (module3_broadcast_ok),
|
|
.BROADCAST_STROBE (module3_strobe),
|
|
.BROADCAST_ADDRESS (module3_address),
|
|
.BROADCAST_DATA (module3_data),
|
|
.BROADCAST_IP (module3_ip),
|
|
.BROADCAST_SYNC (module3_sync),
|
|
.BROADCAST_IDSBL (module3_idsbl),
|
|
|
|
.BROADCAST_OK_IN0 (module0_broadcast_ok),
|
|
.BROADCAST_STROBE_IN0 (module0_strobe),
|
|
.BROADCAST_ADDRESS_IN0 (module0_address),
|
|
.BROADCAST_DATA_IN0 (module0_data),
|
|
.BROADCAST_IP_IN0 (module0_ip),
|
|
.BROADCAST_SYNC_IN0 (module0_sync),
|
|
.BROADCAST_IDSBL_IN0 (module0_idsbl),
|
|
|
|
.BROADCAST_OK_IN1 (module1_broadcast_ok),
|
|
.BROADCAST_STROBE_IN1 (module1_strobe),
|
|
.BROADCAST_ADDRESS_IN1 (module1_address),
|
|
.BROADCAST_DATA_IN1 (module1_data),
|
|
.BROADCAST_IP_IN1 (module1_ip),
|
|
.BROADCAST_SYNC_IN1 (module1_sync),
|
|
.BROADCAST_IDSBL_IN1 (module1_idsbl),
|
|
|
|
.BROADCAST_OK_IN2 (module2_broadcast_ok),
|
|
.BROADCAST_STROBE_IN2 (module2_strobe),
|
|
.BROADCAST_ADDRESS_IN2 (module2_address),
|
|
.BROADCAST_DATA_IN2 (module2_data),
|
|
.BROADCAST_IP_IN2 (module2_ip),
|
|
.BROADCAST_SYNC_IN2 (module2_sync),
|
|
.BROADCAST_IDSBL_IN2 (module2_idsbl),
|
|
|
|
. INT2 (interrupt2),
|
|
. INT3 (interrupt3),
|
|
|
|
.PROXY_RD_DATA (proxy_rd_data_int)
|
|
|
|
);
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
// Fixed-priority arbiter that chooses which
|
|
// core's outputs to direct to the peripherals.
|
|
//
|
|
|
|
assign top_strobe = (module0_broadcast_ok==1'b1) ? module0_strobe :
|
|
(module1_broadcast_ok==1'b1) ? module1_strobe :
|
|
(module2_broadcast_ok==1'b1) ? module2_strobe :
|
|
(module3_broadcast_ok==1'b1) ? module3_strobe :
|
|
8'hEE;
|
|
|
|
|
|
assign top_address = (module0_broadcast_ok==1'b1) ? module0_address :
|
|
(module1_broadcast_ok==1'b1) ? module1_address :
|
|
(module2_broadcast_ok==1'b1) ? module2_address :
|
|
(module3_broadcast_ok==1'b1) ? module3_address :
|
|
16'hEEEE;
|
|
|
|
|
|
|
|
assign top_data = (module0_broadcast_ok==1'b1) ? module0_data :
|
|
(module1_broadcast_ok==1'b1) ? module1_data :
|
|
(module2_broadcast_ok==1'b1) ? module2_data :
|
|
(module3_broadcast_ok==1'b1) ? module3_data :
|
|
8'hEE;
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
//
|
|
// Proxy addressing for peripherals
|
|
//
|
|
// This code mirrors the module accesses to the proxy addressing
|
|
// registers and buffers them to the peripherals.
|
|
//
|
|
//------------------------------------------------------------------------
|
|
|
|
|
|
always @(posedge core_clk_int)
|
|
begin : PROXY_ADDRESSING
|
|
|
|
if (rst_n_d4==1'b0)
|
|
begin
|
|
proxy_wr <= 'h0;
|
|
proxy_rd <= 'h0;
|
|
proxy_address <= 'h0;
|
|
prody_wr_data <= 'h0;
|
|
end
|
|
|
|
else
|
|
begin
|
|
|
|
if (top_strobe[7:0]==8'h11 && top_address[15:0]==16'h00C1)
|
|
begin
|
|
proxy_wr <= 1'b1;
|
|
prody_wr_data <= top_data;
|
|
end
|
|
else
|
|
begin
|
|
proxy_wr <= 1'b0;
|
|
end
|
|
|
|
if (top_strobe[7:0]==8'h11 && top_address[15:0]==16'h00C2)
|
|
begin
|
|
proxy_rd <= 1'b1;
|
|
proxy_address <= top_data;
|
|
end
|
|
else
|
|
begin
|
|
proxy_rd <= 1'b0;
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
//------------------------------------------------------------------------
|
|
//
|
|
// Peripherals accessed with proxy addressing
|
|
//
|
|
// BIU SFR proxy_address - 0xC2 = Address[7:0]
|
|
// proxy_wr_data - 0xC1 = Write Data and strobe to the peripherals
|
|
// proxy_rd_data - 0xC0 = Read Data from the peripherals
|
|
//
|
|
//
|
|
//
|
|
//------------------------------------------------------------------------
|
|
//
|
|
|
|
// Steer the peripheral read data back to the modules
|
|
//
|
|
assign proxy_rd_data_int = (proxy_address[7:4]==4'h0) ? timer_dataout :
|
|
(proxy_address[7:4]==4'h1) ? uart_dataout :
|
|
8'hEE ;
|
|
|
|
// Gate the peripheral read and write strobes
|
|
assign timer_wr_strobe = (proxy_address[7:4]==4'h0) ? proxy_wr : 1'b0;
|
|
assign uart_wr_strobe = (proxy_address[7:4]==4'h1) ? proxy_wr : 1'b0;
|
|
assign uart_rd_strobe = (proxy_address[7:4]==4'h1) ? proxy_rd : 1'b0;
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
//
|
|
// Timer - Dual output 24-bit programmable timer
|
|
//
|
|
// Timer-0 = Frequency generator
|
|
// Timer-1 = Pulse generator
|
|
//
|
|
//------------------------------------------------------------------------
|
|
|
|
timer TIMER
|
|
(
|
|
.CORE_CLK (core_clk_int),
|
|
.RST_n (rst_n_d4),
|
|
.ADDRESS (proxy_address[3:0]),
|
|
.DATA_IN (prody_wr_data),
|
|
.DATA_OUT (timer_dataout),
|
|
.STROBE_WR (timer_wr_strobe),
|
|
.TIMER0_OUT (speaker_int),
|
|
.TIMER1_OUT (interrupt2)
|
|
);
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
//
|
|
// UART - Fixed 9600 baud
|
|
//
|
|
//------------------------------------------------------------------------
|
|
|
|
uart UART
|
|
(
|
|
.CLK (core_clk_int),
|
|
.RST_n (rst_n_d4),
|
|
.ADDRESS (proxy_address[1:0]),
|
|
.DATA_IN (prody_wr_data),
|
|
.DATA_OUT (uart_dataout),
|
|
.STROBE_RD (uart_rd_strobe),
|
|
.STROBE_WR (uart_wr_strobe),
|
|
.UART_RX (UART_RX),
|
|
.UART_TX (UART_TX),
|
|
.UART_INT (interrupt3)
|
|
);
|
|
|
|
|
|
endmodule // four_module_lockstep.v
|