New Verilog and Coq sample files added

New Verilog examples and Coq examples for additional training have
been added since linguist is currently failing Coq/Verilog recognition
tasks (see #201). In case it wasn't obvious, linguist will not
currently pass these new, added test cases.
This commit is contained in:
Schuyler Eldridge
2012-07-20 10:49:12 -04:00
parent 1ac6e87b75
commit 7363241531
23 changed files with 8321 additions and 0 deletions

View File

@@ -0,0 +1,94 @@
////////////////////////////////////////////////////////////////////////////////
// Original Author: Schuyler Eldridge
// Contact Point: Schuyler Eldridge (schuyler.eldridge@gmail.com)
// button_debounce.v
// Created: 10/10/2009
// Modified: 3/20/2012
//
// Counter based debounce circuit originally written for EC551 (back
// in the day) and then modified (i.e. chagned entirely) into 3 always
// block format. This debouncer generates a signal that goes high for
// 1 clock cycle after the clock sees an asserted value on the button
// line. This action is then disabled until the counter hits a
// specified count value that is determined by the clock frequency and
// desired debounce frequency. An alternative implementation would not
// use a counter, but would use the shift register approach, looking
// for repeated matches (say 5) on the button line.
//
// Copyright (C) 2012 Schuyler Eldridge, Boston University
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
////////////////////////////////////////////////////////////////////////////////
`timescale 1ns / 1ps
module button_debounce
(
input clk, // clock
input reset_n, // asynchronous reset
input button, // bouncy button
output reg debounce // debounced 1-cycle signal
);
parameter
CLK_FREQUENCY = 66000000,
DEBOUNCE_HZ = 2;
// These parameters are specified such that you can choose any power
// of 2 frequency for a debouncer between 1 Hz and
// CLK_FREQUENCY. Note, that this will throw errors if you choose a
// non power of 2 frequency (i.e. count_value evaluates to some
// number / 3 which isn't interpreted as a logical right shift). I'm
// assuming this will not work for DEBOUNCE_HZ values less than 1,
// however, I'm uncertain of the value of a debouncer for fractional
// hertz button presses.
localparam
COUNT_VALUE = CLK_FREQUENCY / DEBOUNCE_HZ,
WAIT = 0,
FIRE = 1,
COUNT = 2;
reg [1:0] state, next_state;
reg [25:0] count;
always @ (posedge clk or negedge reset_n)
state <= (!reset_n) ? WAIT : next_state;
always @ (posedge clk or negedge reset_n) begin
if (!reset_n) begin
debounce <= 0;
count <= 0;
end
else begin
debounce <= 0;
count <= 0;
case (state)
WAIT: begin
end
FIRE: begin
debounce <= 1;
end
COUNT: begin
count <= count + 1;
end
endcase
end
end
always @ * begin
case (state)
WAIT: next_state = (button) ? FIRE : state;
FIRE: next_state = COUNT;
COUNT: next_state = (count > COUNT_VALUE - 1) ? WAIT : state;
default: next_state = WAIT;
endcase
end
endmodule

155
samples/verilog/control.v Executable file
View File

@@ -0,0 +1,155 @@
`timescale 1ns / 1ps
// Copyright (C) 2008 Schuyler Eldridge, Boston University
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
module control(clk,en,dsp_sel,an);
input clk, en;
output [1:0]dsp_sel;
output [3:0]an;
wire a,b,c,d,e,f,g,h,i,j,k,l;
assign an[3] = a;
assign an[2] = b;
assign an[1] = c;
assign an[0] = d;
assign dsp_sel[1] = e;
assign dsp_sel[0] = i;
FDRSE #(
.INIT(1'b0) // Initial value of register (1'b0 or 1'b1)
) DFF3(
.Q(a), // Data output
.C(clk), // Clock input
.CE(en), // Clock enable input
.D(d), // Data input
.R(1'b0), // Synchronous reset input
.S(1'b0) // Synchronous set input
);
FDRSE #(
.INIT(1'b1) // Initial value of register (1'b0 or 1'b1)
) DFF2(
.Q(b), // Data output
.C(clk), // Clock input
.CE(en), // Clock enable input
.D(a), // Data input
.R(1'b0), // Synchronous reset input
.S(1'b0) // Synchronous set input
);
FDRSE #(
.INIT(1'b1) // Initial value of register (1'b0 or 1'b1)
) DFF1(
.Q(c), // Data output
.C(clk), // Clock input
.CE(en), // Clock enable input
.D(b), // Data input
.R(1'b0), // Synchronous reset input
.S(1'b0) // Synchronous set input
);
FDRSE #(
.INIT(1'b1) // Initial value of register (1'b0 or 1'b1)
) DFF0(
.Q(d), // Data output
.C(clk), // Clock input
.CE(en), // Clock enable input
.D(c), // Data input
.R(1'b0), // Synchronous reset input
.S(1'b0) // Synchronous set input
);
FDRSE #(
.INIT(1'b1) // Initial value of register (1'b0 or 1'b1)
) DFF7(
.Q(e), // Data output
.C(clk), // Clock input
.CE(en), // Clock enable input
.D(h), // Data input
.R(1'b0), // Synchronous reset input
.S(1'b0) // Synchronous set input
);
FDRSE #(
.INIT(1'b1) // Initial value of register (1'b0 or 1'b1)
) DFF6(
.Q(f), // Data output
.C(clk), // Clock input
.CE(en), // Clock enable input
.D(e), // Data input
.R(1'b0), // Synchronous reset input
.S(1'b0) // Synchronous set input
);
FDRSE #(
.INIT(1'b0) // Initial value of register (1'b0 or 1'b1)
) DFF5(
.Q(g), // Data output
.C(clk), // Clock input
.CE(en), // Clock enable input
.D(f), // Data input
.R(1'b0), // Synchronous reset input
.S(1'b0) // Synchronous set input
);
FDRSE #(
.INIT(1'b0) // Initial value of register (1'b0 or 1'b1)
) DFF4(
.Q(h), // Data output
.C(clk), // Clock input
.CE(en), // Clock enable input
.D(g), // Data input
.R(1'b0), // Synchronous reset input
.S(1'b0) // Synchronous set input
);
FDRSE #(
.INIT(1'b1) // Initial value of register (1'b0 or 1'b1)
) DFF11(
.Q(i), // Data output
.C(clk), // Clock input
.CE(en), // Clock enable input
.D(l), // Data input
.R(1'b0), // Synchronous reset input
.S(1'b0) // Synchronous set input
);
FDRSE #(
.INIT(1'b0) // Initial value of register (1'b0 or 1'b1)
) DFF10(
.Q(j), // Data output
.C(clk), // Clock input
.CE(en), // Clock enable input
.D(i), // Data input
.R(1'b0), // Synchronous reset input
.S(1'b0) // Synchronous set input
);
FDRSE #(
.INIT(1'b1) // Initial value of register (1'b0 or 1'b1)
) DFF9(
.Q(k), // Data output
.C(clk), // Clock input
.CE(en), // Clock enable input
.D(j), // Data input
.R(1'b0), // Synchronous reset input
.S(1'b0) // Synchronous set input
);
FDRSE #(
.INIT(1'b0) // Initial value of register (1'b0 or 1'b1)
) DFF8(
.Q(l), // Data output
.C(clk), // Clock input
.CE(en), // Clock enable input
.D(k), // Data input
.R(1'b0), // Synchronous reset input
.S(1'b0) // Synchronous set input
);
endmodule

54
samples/verilog/hex_display.v Executable file
View File

@@ -0,0 +1,54 @@
/*
* Copyright (c) 2009 Zeus Gomez Marmolejo <zeus@opencores.org>
*
* This file is part of the Zet processor. This processor is free
* hardware; you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software
* Foundation; either version 3, or (at your option) any later version.
*
* Zet is distrubuted in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Zet; see the file COPYING. If not, see
* <http://www.gnu.org/licenses/>.
*/
module hex_display (
input [15:0] num,
input en,
output [6:0] hex0,
output [6:0] hex1,
output [6:0] hex2,
output [6:0] hex3
);
// Module instantiations
seg_7 hex_group0 (
.num (num[3:0]),
.en (en),
.seg (hex0)
);
seg_7 hex_group1 (
.num (num[7:4]),
.en (en),
.seg (hex1)
);
seg_7 hex_group2 (
.num (num[11:8]),
.en (en),
.seg (hex2)
);
seg_7 hex_group3 (
.num (num[15:12]),
.en (en),
.seg (hex3)
);
endmodule

45
samples/verilog/mux.v Executable file
View File

@@ -0,0 +1,45 @@
`timescale 1ns / 1ps
// Copyright (C) 2008 Schuyler Eldridge, Boston University
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
module mux(opA,opB,sum,dsp_sel,out);
input [3:0] opA,opB;
input [4:0] sum;
input [1:0] dsp_sel;
output [3:0] out;
reg cout;
always @ (sum)
begin
if (sum[4] == 1)
cout <= 4'b0001;
else
cout <= 4'b0000;
end
reg out;
always @(dsp_sel,sum,cout,opB,opA)
begin
if (dsp_sel == 2'b00)
out <= sum[3:0];
else if (dsp_sel == 2'b01)
out <= cout;
else if (dsp_sel == 2'b10)
out <= opB;
else if (dsp_sel == 2'b11)
out <= opA;
end
endmodule

View File

@@ -0,0 +1,82 @@
////////////////////////////////////////////////////////////////////////////////
// Original Author: Schuyler Eldridge
// Contact Point: Schuyler Eldridge (schuyler.eldridge@gmail.com)
// pipeline_registers.v
// Created: 4.4.2012
// Modified: 4.4.2012
//
// Implements a series of pipeline registers specified by the input
// parameters BIT_WIDTH and NUMBER_OF_STAGES. BIT_WIDTH determines the
// size of the signal passed through each of the pipeline
// registers. NUMBER_OF_STAGES is the number of pipeline registers
// generated. This accepts values of 0 (yes, it just passes data from
// input to output...) up to however many stages specified.
// Copyright (C) 2012 Schuyler Eldridge, Boston University
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
////////////////////////////////////////////////////////////////////////////////
`timescale 1ns / 1ps
module pipeline_registers
(
input clk,
input reset_n,
input [BIT_WIDTH-1:0] pipe_in,
output reg [BIT_WIDTH-1:0] pipe_out
);
// WARNING!!! THESE PARAMETERS ARE INTENDED TO BE MODIFIED IN A TOP
// LEVEL MODULE. LOCAL CHANGES HERE WILL, MOST LIKELY, BE
// OVERWRITTEN!
parameter
BIT_WIDTH = 10,
NUMBER_OF_STAGES = 5;
// Main generate function for conditional hardware instantiation
generate
genvar i;
// Pass-through case for the odd event that no pipeline stages are
// specified.
if (NUMBER_OF_STAGES == 0) begin
always @ *
pipe_out = pipe_in;
end
// Single flop case for a single stage pipeline
else if (NUMBER_OF_STAGES == 1) begin
always @ (posedge clk or negedge reset_n)
pipe_out <= (!reset_n) ? 0 : pipe_in;
end
// Case for 2 or more pipeline stages
else begin
// Create the necessary regs
reg [BIT_WIDTH*(NUMBER_OF_STAGES-1)-1:0] pipe_gen;
// Create logic for the initial and final pipeline registers
always @ (posedge clk or negedge reset_n) begin
if (!reset_n) begin
pipe_gen[BIT_WIDTH-1:0] <= 0;
pipe_out <= 0;
end
else begin
pipe_gen[BIT_WIDTH-1:0] <= pipe_in;
pipe_out <= pipe_gen[BIT_WIDTH*(NUMBER_OF_STAGES-1)-1:BIT_WIDTH*(NUMBER_OF_STAGES-2)];
end
end
// Create the intermediate pipeline registers if there are 3 or
// more pipeline stages
for (i = 1; i < NUMBER_OF_STAGES-1; i = i + 1) begin : pipeline
always @ (posedge clk or negedge reset_n)
pipe_gen[BIT_WIDTH*(i+1)-1:BIT_WIDTH*i] <= (!reset_n) ? 0 : pipe_gen[BIT_WIDTH*i-1:BIT_WIDTH*(i-1)];
end
end
endgenerate
endmodule

175
samples/verilog/ps2_mouse.v Executable file
View File

@@ -0,0 +1,175 @@
/*
* PS2 Mouse Interface
* Copyright (C) 2010 Donna Polehn <dpolehn@verizon.net>
*
* This file is part of the Zet processor. This processor is free
* hardware; you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software
* Foundation; either version 3, or (at your option) any later version.
*
* Zet is distrubuted in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Zet; see the file COPYING. If not, see
* <http://www.gnu.org/licenses/>.
*/
module ps2_mouse (
input clk, // Clock Input
input reset, // Reset Input
inout ps2_clk, // PS2 Clock, Bidirectional
inout ps2_dat, // PS2 Data, Bidirectional
input [7:0] the_command, // Command to send to mouse
input send_command, // Signal to send
output command_was_sent, // Signal command finished sending
output error_communication_timed_out,
output [7:0] received_data, // Received data
output received_data_en, // If 1 - new data has been received
output start_receiving_data,
output wait_for_incoming_data
);
// --------------------------------------------------------------------
// Internal wires and registers Declarations
// --------------------------------------------------------------------
wire ps2_clk_posedge; // Internal Wires
wire ps2_clk_negedge;
reg [7:0] idle_counter; // Internal Registers
reg ps2_clk_reg;
reg ps2_data_reg;
reg last_ps2_clk;
reg [2:0] ns_ps2_transceiver; // State Machine Registers
reg [2:0] s_ps2_transceiver;
// --------------------------------------------------------------------
// Constant Declarations
// --------------------------------------------------------------------
localparam PS2_STATE_0_IDLE = 3'h0, // states
PS2_STATE_1_DATA_IN = 3'h1,
PS2_STATE_2_COMMAND_OUT = 3'h2,
PS2_STATE_3_END_TRANSFER = 3'h3,
PS2_STATE_4_END_DELAYED = 3'h4;
// --------------------------------------------------------------------
// Finite State Machine(s)
// --------------------------------------------------------------------
always @(posedge clk) begin
if(reset == 1'b1) s_ps2_transceiver <= PS2_STATE_0_IDLE;
else s_ps2_transceiver <= ns_ps2_transceiver;
end
always @(*) begin
ns_ps2_transceiver = PS2_STATE_0_IDLE; // Defaults
case (s_ps2_transceiver)
PS2_STATE_0_IDLE:
begin
if((idle_counter == 8'hFF) && (send_command == 1'b1))
ns_ps2_transceiver = PS2_STATE_2_COMMAND_OUT;
else if ((ps2_data_reg == 1'b0) && (ps2_clk_posedge == 1'b1))
ns_ps2_transceiver = PS2_STATE_1_DATA_IN;
else ns_ps2_transceiver = PS2_STATE_0_IDLE;
end
PS2_STATE_1_DATA_IN:
begin
// if((received_data_en == 1'b1) && (ps2_clk_posedge == 1'b1))
if((received_data_en == 1'b1)) ns_ps2_transceiver = PS2_STATE_0_IDLE;
else ns_ps2_transceiver = PS2_STATE_1_DATA_IN;
end
PS2_STATE_2_COMMAND_OUT:
begin
if((command_was_sent == 1'b1) || (error_communication_timed_out == 1'b1))
ns_ps2_transceiver = PS2_STATE_3_END_TRANSFER;
else ns_ps2_transceiver = PS2_STATE_2_COMMAND_OUT;
end
PS2_STATE_3_END_TRANSFER:
begin
if(send_command == 1'b0) ns_ps2_transceiver = PS2_STATE_0_IDLE;
else if((ps2_data_reg == 1'b0) && (ps2_clk_posedge == 1'b1))
ns_ps2_transceiver = PS2_STATE_4_END_DELAYED;
else ns_ps2_transceiver = PS2_STATE_3_END_TRANSFER;
end
PS2_STATE_4_END_DELAYED:
begin
if(received_data_en == 1'b1) begin
if(send_command == 1'b0) ns_ps2_transceiver = PS2_STATE_0_IDLE;
else ns_ps2_transceiver = PS2_STATE_3_END_TRANSFER;
end
else ns_ps2_transceiver = PS2_STATE_4_END_DELAYED;
end
default:
ns_ps2_transceiver = PS2_STATE_0_IDLE;
endcase
end
// --------------------------------------------------------------------
// Sequential logic
// --------------------------------------------------------------------
always @(posedge clk) begin
if(reset == 1'b1) begin
last_ps2_clk <= 1'b1;
ps2_clk_reg <= 1'b1;
ps2_data_reg <= 1'b1;
end
else begin
last_ps2_clk <= ps2_clk_reg;
ps2_clk_reg <= ps2_clk;
ps2_data_reg <= ps2_dat;
end
end
always @(posedge clk) begin
if(reset == 1'b1) idle_counter <= 6'h00;
else if((s_ps2_transceiver == PS2_STATE_0_IDLE) && (idle_counter != 8'hFF))
idle_counter <= idle_counter + 6'h01;
else if (s_ps2_transceiver != PS2_STATE_0_IDLE)
idle_counter <= 6'h00;
end
// --------------------------------------------------------------------
// Combinational logic
// --------------------------------------------------------------------
assign ps2_clk_posedge = ((ps2_clk_reg == 1'b1) && (last_ps2_clk == 1'b0)) ? 1'b1 : 1'b0;
assign ps2_clk_negedge = ((ps2_clk_reg == 1'b0) && (last_ps2_clk == 1'b1)) ? 1'b1 : 1'b0;
assign start_receiving_data = (s_ps2_transceiver == PS2_STATE_1_DATA_IN);
assign wait_for_incoming_data = (s_ps2_transceiver == PS2_STATE_3_END_TRANSFER);
// --------------------------------------------------------------------
// Internal Modules
// --------------------------------------------------------------------
ps2_mouse_cmdout mouse_cmdout (
.clk (clk), // Inputs
.reset (reset),
.the_command (the_command),
.send_command (send_command),
.ps2_clk_posedge (ps2_clk_posedge),
.ps2_clk_negedge (ps2_clk_negedge),
.ps2_clk (ps2_clk), // Bidirectionals
.ps2_dat (ps2_dat),
.command_was_sent (command_was_sent), // Outputs
.error_communication_timed_out (error_communication_timed_out)
);
ps2_mouse_datain mouse_datain (
.clk (clk), // Inputs
.reset (reset),
.wait_for_incoming_data (wait_for_incoming_data),
.start_receiving_data (start_receiving_data),
.ps2_clk_posedge (ps2_clk_posedge),
.ps2_clk_negedge (ps2_clk_negedge),
.ps2_data (ps2_data_reg),
.received_data (received_data), // Outputs
.received_data_en (received_data_en)
);
endmodule

49
samples/verilog/sign_extender.v Executable file
View File

@@ -0,0 +1,49 @@
////////////////////////////////////////////////////////////////////////////////
// Original Author: Schuyler Eldridge
// Contact Point: Schuyler Eldridge (schuyler.eldridge@gmail.com)
// sign_extender.v
// Created: 5.16.2012
// Modified: 5.16.2012
//
// Generic sign extension module
//
// Copyright (C) 2012 Schuyler Eldridge, Boston University
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
////////////////////////////////////////////////////////////////////////////////
`timescale 1ns/1ps
module sign_extender
#(
parameter
INPUT_WIDTH = 8,
OUTPUT_WIDTH = 16
)
(
input [INPUT_WIDTH-1:0] original,
output reg [OUTPUT_WIDTH-1:0] sign_extended_original
);
wire [OUTPUT_WIDTH-INPUT_WIDTH-1:0] sign_extend;
generate
genvar i;
for (i = 0; i < OUTPUT_WIDTH-INPUT_WIDTH; i = i + 1) begin : gen_sign_extend
assign sign_extend[i] = (original[INPUT_WIDTH-1]) ? 1'b1 : 1'b0;
end
endgenerate
always @ * begin
sign_extended_original = {sign_extend,original};
end
endmodule

154
samples/verilog/sqrt_pipelined.v Executable file
View File

@@ -0,0 +1,154 @@
////////////////////////////////////////////////////////////////////////////////
// Original Author: Schuyler Eldridge
// Contact Point: Schuyler Eldridge (schuyler.eldridge@gmail.com)
// sqrt_pipelined.v
// Created: 4.2.2012
// Modified: 4.5.2012
//
// Implements a fixed-point parameterized pipelined square root
// operation on an unsigned input of any bit length. The number of
// stages in the pipeline is equal to the number of output bits in the
// computation. This pipelien sustains a throughput of one computation
// per clock cycle.
//
// Copyright (C) 2012 Schuyler Eldridge, Boston University
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
////////////////////////////////////////////////////////////////////////////////
`timescale 1ns / 1ps
module sqrt_pipelined
(
input clk, // clock
input reset_n, // asynchronous reset
input start, // optional start signal
input [INPUT_BITS-1:0] radicand, // unsigned radicand
output reg data_valid, // optional data valid signal
output reg [OUTPUT_BITS-1:0] root // unsigned root
);
// WARNING!!! THESE PARAMETERS ARE INTENDED TO BE MODIFIED IN A TOP
// LEVEL MODULE. LOCAL CHANGES HERE WILL, MOST LIKELY, BE
// OVERWRITTEN!
parameter
INPUT_BITS = 16; // number of input bits (any integer)
localparam
OUTPUT_BITS = INPUT_BITS / 2 + INPUT_BITS % 2; // number of output bits
reg [OUTPUT_BITS-1:0] start_gen; // valid data propagation
reg [OUTPUT_BITS*INPUT_BITS-1:0] root_gen; // root values
reg [OUTPUT_BITS*INPUT_BITS-1:0] radicand_gen; // radicand values
wire [OUTPUT_BITS*INPUT_BITS-1:0] mask_gen; // mask values
// This is the first stage of the pipeline.
always @ (posedge clk or negedge reset_n) begin
if (!reset_n) begin
start_gen[0] <= 0;
radicand_gen[INPUT_BITS-1:0] <= 0;
root_gen[INPUT_BITS-1:0] <= 0;
end
else begin
start_gen[0] <= start;
if ( mask_gen[INPUT_BITS-1:0] <= radicand ) begin
radicand_gen[INPUT_BITS-1:0] <= radicand - mask_gen[INPUT_BITS-1:0];
root_gen[INPUT_BITS-1:0] <= mask_gen[INPUT_BITS-1:0];
end
else begin
radicand_gen[INPUT_BITS-1:0] <= radicand;
root_gen[INPUT_BITS-1:0] <= 0;
end
end
end
// Main generate loop to create the masks and pipeline stages.
generate
genvar i;
// Generate all the mask values. These are built up in the
// following fashion:
// LAST MASK: 0x00...001
// 0x00...004 Increasing # OUTPUT_BITS
// 0x00...010 |
// 0x00...040 v
// ...
// FIRST MASK: 0x10...000 # masks == # OUTPUT_BITS
//
// Note that the first mask used can either be of the 0x1... or
// 0x4... variety. This is purely determined by the number of
// computation stages. However, the last mask used will always be
// 0x1 and the second to last mask used will always be 0x4.
for (i = 0; i < OUTPUT_BITS; i = i + 1) begin: mask_4
if (i % 2) // i is odd, this is a 4 mask
assign mask_gen[INPUT_BITS*(OUTPUT_BITS-i)-1:INPUT_BITS*(OUTPUT_BITS-i-1)] = 4 << 4 * (i/2);
else // i is even, this is a 1 mask
assign mask_gen[INPUT_BITS*(OUTPUT_BITS-i)-1:INPUT_BITS*(OUTPUT_BITS-i-1)] = 1 << 4 * (i/2);
end
// Generate all the pipeline stages to compute the square root of
// the input radicand stream. The general approach is to compare
// the current values of the root plus the mask to the
// radicand. If root/mask sum is greater than the radicand,
// subtract the mask and the root from the radicand and store the
// radicand for the next stage. Additionally, the root is
// increased by the value of the mask and stored for the next
// stage. If this test fails, then the radicand and the root
// retain their value through to the next stage. The one weird
// thing is that the mask indices appear to be incremented by one
// additional position. This is not the case, however, because the
// first mask is used in the first stage (always block after the
// generate statement).
for (i = 0; i < OUTPUT_BITS - 1; i = i + 1) begin: pipeline
always @ (posedge clk or negedge reset_n) begin : pipeline_stage
if (!reset_n) begin
start_gen[i+1] <= 0;
radicand_gen[INPUT_BITS*(i+2)-1:INPUT_BITS*(i+1)] <= 0;
root_gen[INPUT_BITS*(i+2)-1:INPUT_BITS*(i+1)] <= 0;
end
else begin
start_gen[i+1] <= start_gen[i];
if ((root_gen[INPUT_BITS*(i+1)-1:INPUT_BITS*i] +
mask_gen[INPUT_BITS*(i+2)-1:INPUT_BITS*(i+1)]) <= radicand_gen[INPUT_BITS*(i+1)-1:INPUT_BITS*i]) begin
radicand_gen[INPUT_BITS*(i+2)-1:INPUT_BITS*(i+1)] <= radicand_gen[INPUT_BITS*(i+1)-1:INPUT_BITS*i] -
mask_gen[INPUT_BITS*(i+2)-1:INPUT_BITS*(i+1)] -
root_gen[INPUT_BITS*(i+1)-1:INPUT_BITS*i];
root_gen[INPUT_BITS*(i+2)-1:INPUT_BITS*(i+1)] <= (root_gen[INPUT_BITS*(i+1)-1:INPUT_BITS*i] >> 1) +
mask_gen[INPUT_BITS*(i+2)-1:INPUT_BITS*(i+1)];
end
else begin
radicand_gen[INPUT_BITS*(i+2)-1:INPUT_BITS*(i+1)] <= radicand_gen[INPUT_BITS*(i+1)-1:INPUT_BITS*i];
root_gen[INPUT_BITS*(i+2)-1:INPUT_BITS*(i+1)] <= root_gen[INPUT_BITS*(i+1)-1:INPUT_BITS*i] >> 1;
end
end
end
end
endgenerate
// This is the final stage which just implements a rounding
// operation. This stage could be tacked on as a combinational logic
// stage, but who cares about latency, anyway? This is NOT a true
// rounding stage. In order to add convergent rounding, you need to
// increase the input bit width by 2 (increase the number of
// pipeline stages by 1) and implement rounding in the module that
// instantiates this one.
always @ (posedge clk or negedge reset_n) begin
if (!reset_n) begin
data_valid <= 0;
root <= 0;
end
else begin
data_valid <= start_gen[OUTPUT_BITS-1];
if (root_gen[OUTPUT_BITS*INPUT_BITS-1:OUTPUT_BITS*INPUT_BITS-INPUT_BITS] > root_gen[OUTPUT_BITS*INPUT_BITS-1:OUTPUT_BITS*INPUT_BITS-INPUT_BITS])
root <= root_gen[OUTPUT_BITS*INPUT_BITS-1:OUTPUT_BITS*INPUT_BITS-INPUT_BITS] + 1;
else
root <= root_gen[OUTPUT_BITS*INPUT_BITS-1:OUTPUT_BITS*INPUT_BITS-INPUT_BITS];
end
end
endmodule

View File

@@ -0,0 +1,70 @@
////////////////////////////////////////////////////////////////////////////////
// Original Author: Schuyler Eldridge
// Contact Point: Schuyler Eldridge (schuyler.eldridge@gmail.com)
// button_debounce.v
// Created: 4.5.2012
// Modified: 4.5.2012
//
// Testbench for button_debounce.v.
//
// Copyright (C) 2012 Schuyler Eldridge, Boston University
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
////////////////////////////////////////////////////////////////////////////////
`timescale 1ns / 1ps
module t_button_debounce();
parameter
CLK_FREQUENCY = 66000000,
DEBOUNCE_HZ = 2;
reg clk, reset_n, button;
wire debounce;
button_debounce
#(
.CLK_FREQUENCY(CLK_FREQUENCY),
.DEBOUNCE_HZ(DEBOUNCE_HZ)
)
button_debounce
(
.clk(clk),
.reset_n(reset_n),
.button(button),
.debounce(debounce)
);
initial begin
clk = 1'bx; reset_n = 1'bx; button = 1'bx;
#10 reset_n = 1;
#10 reset_n = 0; clk = 0;
#10 reset_n = 1;
#10 button = 0;
end
always
#5 clk = ~clk;
always begin
#100 button = ~button;
#0.1 button = ~button;
#0.1 button = ~button;
#0.1 button = ~button;
#0.1 button = ~button;
#0.1 button = ~button;
#0.1 button = ~button;
#0.1 button = ~button;
#0.1 button = ~button;
end
endmodule

View File

@@ -0,0 +1,75 @@
////////////////////////////////////////////////////////////////////////////////
// Original Author: Schuyler Eldridge
// Contact Point: Schuyler Eldridge (schuyler.eldridge@gmail.com)
// div_pipelined.v
// Created: 4.3.2012
// Modified: 4.5.2012
//
// Testbench for div_pipelined.v
//
// Copyright (C) 2012 Schuyler Eldridge, Boston University
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
////////////////////////////////////////////////////////////////////////////////
`timescale 1ns / 1ps
module t_div_pipelined();
reg clk, start, reset_n;
reg [7:0] dividend, divisor;
wire data_valid, div_by_zero;
wire [7:0] quotient, quotient_correct;
parameter
BITS = 8;
div_pipelined
#(
.BITS(BITS)
)
div_pipelined
(
.clk(clk),
.reset_n(reset_n),
.dividend(dividend),
.divisor(divisor),
.quotient(quotient),
.div_by_zero(div_by_zero),
// .quotient_correct(quotient_correct),
.start(start),
.data_valid(data_valid)
);
initial begin
#10 reset_n = 0;
#50 reset_n = 1;
#1
clk = 0;
dividend = -1;
divisor = 127;
#1000 $finish;
end
// always
// #20 dividend = dividend + 1;
always begin
#10 divisor = divisor - 1; start = 1;
#10 start = 0;
end
always
#5 clk = ~clk;
endmodule

View File

@@ -0,0 +1,77 @@
////////////////////////////////////////////////////////////////////////////////
// Original Author: Schuyler Eldridge
// Contact Point: Schuyler Eldridge (schuyler.eldridge@gmail.com)
// t_sqrt_pipelined.v
// Created: 4.2.2012
// Modified: 4.5.2012
//
// Testbench for generic sqrt operation
//
// Copyright (C) 2012 Schuyler Eldridge, Boston University
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
////////////////////////////////////////////////////////////////////////////////
`timescale 1ns / 1ps
module t_sqrt_pipelined();
parameter
INPUT_BITS = 4;
localparam
OUTPUT_BITS = INPUT_BITS / 2 + INPUT_BITS % 2;
reg [INPUT_BITS-1:0] radicand;
reg clk, start, reset_n;
wire [OUTPUT_BITS-1:0] root;
wire data_valid;
// wire [7:0] root_good;
sqrt_pipelined
#(
.INPUT_BITS(INPUT_BITS)
)
sqrt_pipelined
(
.clk(clk),
.reset_n(reset_n),
.start(start),
.radicand(radicand),
.data_valid(data_valid),
.root(root)
);
initial begin
radicand = 16'bx; clk = 1'bx; start = 1'bx; reset_n = 1'bx;;
#10 reset_n = 0; clk = 0;
#50 reset_n = 1; radicand = 0;
// #40 radicand = 81; start = 1;
// #10 radicand = 16'bx; start = 0;
#10000 $finish;
end
always
#5 clk = ~clk;
always begin
#10 radicand = radicand + 1; start = 1;
#10 start = 0;
end
// always begin
// #80 start = 1;
// #10 start = 0;
// end
endmodule

313
samples/verilog/vga.v Executable file
View File

@@ -0,0 +1,313 @@
/*
* VGA top level file
* Copyright (C) 2010 Zeus Gomez Marmolejo <zeus@aluzina.org>
*
* This file is part of the Zet processor. This processor is free
* hardware; you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software
* Foundation; either version 3, or (at your option) any later version.
*
* Zet is distrubuted in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Zet; see the file COPYING. If not, see
* <http://www.gnu.org/licenses/>.
*/
module vga (
// Wishbone signals
input wb_clk_i, // 25 Mhz VDU clock
input wb_rst_i,
input [15:0] wb_dat_i,
output [15:0] wb_dat_o,
input [16:1] wb_adr_i,
input wb_we_i,
input wb_tga_i,
input [ 1:0] wb_sel_i,
input wb_stb_i,
input wb_cyc_i,
output wb_ack_o,
// VGA pad signals
output [ 3:0] vga_red_o,
output [ 3:0] vga_green_o,
output [ 3:0] vga_blue_o,
output horiz_sync,
output vert_sync,
// CSR SRAM master interface
output [17:1] csrm_adr_o,
output [ 1:0] csrm_sel_o,
output csrm_we_o,
output [15:0] csrm_dat_o,
input [15:0] csrm_dat_i
);
// Registers and nets
//
// csr address
reg [17:1] csr_adr_i;
reg csr_stb_i;
// Config wires
wire [15:0] conf_wb_dat_o;
wire conf_wb_ack_o;
// Mem wires
wire [15:0] mem_wb_dat_o;
wire mem_wb_ack_o;
// LCD wires
wire [17:1] csr_adr_o;
wire [15:0] csr_dat_i;
wire csr_stb_o;
wire v_retrace;
wire vh_retrace;
wire w_vert_sync;
// VGA configuration registers
wire shift_reg1;
wire graphics_alpha;
wire memory_mapping1;
wire [ 1:0] write_mode;
wire [ 1:0] raster_op;
wire read_mode;
wire [ 7:0] bitmask;
wire [ 3:0] set_reset;
wire [ 3:0] enable_set_reset;
wire [ 3:0] map_mask;
wire x_dotclockdiv2;
wire chain_four;
wire [ 1:0] read_map_select;
wire [ 3:0] color_compare;
wire [ 3:0] color_dont_care;
// Wishbone master to SRAM
wire [17:1] wbm_adr_o;
wire [ 1:0] wbm_sel_o;
wire wbm_we_o;
wire [15:0] wbm_dat_o;
wire [15:0] wbm_dat_i;
wire wbm_stb_o;
wire wbm_ack_i;
wire stb;
// CRT wires
wire [ 5:0] cur_start;
wire [ 5:0] cur_end;
wire [15:0] start_addr;
wire [ 4:0] vcursor;
wire [ 6:0] hcursor;
wire [ 6:0] horiz_total;
wire [ 6:0] end_horiz;
wire [ 6:0] st_hor_retr;
wire [ 4:0] end_hor_retr;
wire [ 9:0] vert_total;
wire [ 9:0] end_vert;
wire [ 9:0] st_ver_retr;
wire [ 3:0] end_ver_retr;
// attribute_ctrl wires
wire [3:0] pal_addr;
wire pal_we;
wire [7:0] pal_read;
wire [7:0] pal_write;
// dac_regs wires
wire dac_we;
wire [1:0] dac_read_data_cycle;
wire [7:0] dac_read_data_register;
wire [3:0] dac_read_data;
wire [1:0] dac_write_data_cycle;
wire [7:0] dac_write_data_register;
wire [3:0] dac_write_data;
// Module instances
//
vga_config_iface config_iface (
.wb_clk_i (wb_clk_i),
.wb_rst_i (wb_rst_i),
.wb_dat_i (wb_dat_i),
.wb_dat_o (conf_wb_dat_o),
.wb_adr_i (wb_adr_i[4:1]),
.wb_we_i (wb_we_i),
.wb_sel_i (wb_sel_i),
.wb_stb_i (stb & wb_tga_i),
.wb_ack_o (conf_wb_ack_o),
.shift_reg1 (shift_reg1),
.graphics_alpha (graphics_alpha),
.memory_mapping1 (memory_mapping1),
.write_mode (write_mode),
.raster_op (raster_op),
.read_mode (read_mode),
.bitmask (bitmask),
.set_reset (set_reset),
.enable_set_reset (enable_set_reset),
.map_mask (map_mask),
.x_dotclockdiv2 (x_dotclockdiv2),
.chain_four (chain_four),
.read_map_select (read_map_select),
.color_compare (color_compare),
.color_dont_care (color_dont_care),
.pal_addr (pal_addr),
.pal_we (pal_we),
.pal_read (pal_read),
.pal_write (pal_write),
.dac_we (dac_we),
.dac_read_data_cycle (dac_read_data_cycle),
.dac_read_data_register (dac_read_data_register),
.dac_read_data (dac_read_data),
.dac_write_data_cycle (dac_write_data_cycle),
.dac_write_data_register (dac_write_data_register),
.dac_write_data (dac_write_data),
.cur_start (cur_start),
.cur_end (cur_end),
.start_addr (start_addr),
.vcursor (vcursor),
.hcursor (hcursor),
.horiz_total (horiz_total),
.end_horiz (end_horiz),
.st_hor_retr (st_hor_retr),
.end_hor_retr (end_hor_retr),
.vert_total (vert_total),
.end_vert (end_vert),
.st_ver_retr (st_ver_retr),
.end_ver_retr (end_ver_retr),
.v_retrace (v_retrace),
.vh_retrace (vh_retrace)
);
vga_lcd lcd (
.clk (wb_clk_i),
.rst (wb_rst_i),
.shift_reg1 (shift_reg1),
.graphics_alpha (graphics_alpha),
.pal_addr (pal_addr),
.pal_we (pal_we),
.pal_read (pal_read),
.pal_write (pal_write),
.dac_we (dac_we),
.dac_read_data_cycle (dac_read_data_cycle),
.dac_read_data_register (dac_read_data_register),
.dac_read_data (dac_read_data),
.dac_write_data_cycle (dac_write_data_cycle),
.dac_write_data_register (dac_write_data_register),
.dac_write_data (dac_write_data),
.csr_adr_o (csr_adr_o),
.csr_dat_i (csr_dat_i),
.csr_stb_o (csr_stb_o),
.vga_red_o (vga_red_o),
.vga_green_o (vga_green_o),
.vga_blue_o (vga_blue_o),
.horiz_sync (horiz_sync),
.vert_sync (w_vert_sync),
.cur_start (cur_start),
.cur_end (cur_end),
.vcursor (vcursor),
.hcursor (hcursor),
.horiz_total (horiz_total),
.end_horiz (end_horiz),
.st_hor_retr (st_hor_retr),
.end_hor_retr (end_hor_retr),
.vert_total (vert_total),
.end_vert (end_vert),
.st_ver_retr (st_ver_retr),
.end_ver_retr (end_ver_retr),
.x_dotclockdiv2 (x_dotclockdiv2),
.v_retrace (v_retrace),
.vh_retrace (vh_retrace)
);
vga_cpu_mem_iface cpu_mem_iface (
.wb_clk_i (wb_clk_i),
.wb_rst_i (wb_rst_i),
.wbs_adr_i (wb_adr_i),
.wbs_sel_i (wb_sel_i),
.wbs_we_i (wb_we_i),
.wbs_dat_i (wb_dat_i),
.wbs_dat_o (mem_wb_dat_o),
.wbs_stb_i (stb & !wb_tga_i),
.wbs_ack_o (mem_wb_ack_o),
.wbm_adr_o (wbm_adr_o),
.wbm_sel_o (wbm_sel_o),
.wbm_we_o (wbm_we_o),
.wbm_dat_o (wbm_dat_o),
.wbm_dat_i (wbm_dat_i),
.wbm_stb_o (wbm_stb_o),
.wbm_ack_i (wbm_ack_i),
.chain_four (chain_four),
.memory_mapping1 (memory_mapping1),
.write_mode (write_mode),
.raster_op (raster_op),
.read_mode (read_mode),
.bitmask (bitmask),
.set_reset (set_reset),
.enable_set_reset (enable_set_reset),
.map_mask (map_mask),
.read_map_select (read_map_select),
.color_compare (color_compare),
.color_dont_care (color_dont_care)
);
vga_mem_arbitrer mem_arbitrer (
.clk_i (wb_clk_i),
.rst_i (wb_rst_i),
.wb_adr_i (wbm_adr_o),
.wb_sel_i (wbm_sel_o),
.wb_we_i (wbm_we_o),
.wb_dat_i (wbm_dat_o),
.wb_dat_o (wbm_dat_i),
.wb_stb_i (wbm_stb_o),
.wb_ack_o (wbm_ack_i),
.csr_adr_i (csr_adr_i),
.csr_dat_o (csr_dat_i),
.csr_stb_i (csr_stb_i),
.csrm_adr_o (csrm_adr_o),
.csrm_sel_o (csrm_sel_o),
.csrm_we_o (csrm_we_o),
.csrm_dat_o (csrm_dat_o),
.csrm_dat_i (csrm_dat_i)
);
// Continous assignments
assign wb_dat_o = wb_tga_i ? conf_wb_dat_o : mem_wb_dat_o;
assign wb_ack_o = wb_tga_i ? conf_wb_ack_o : mem_wb_ack_o;
assign stb = wb_stb_i & wb_cyc_i;
assign vert_sync = ~graphics_alpha ^ w_vert_sync;
// Behaviour
// csr_adr_i
always @(posedge wb_clk_i)
csr_adr_i <= wb_rst_i ? 17'h0 : csr_adr_o + start_addr[15:1];
// csr_stb_i
always @(posedge wb_clk_i)
csr_stb_i <= wb_rst_i ? 1'b0 : csr_stb_o;
endmodule