diff --git a/Project2/pattern_detector.v b/Project2/pattern_detector.v new file mode 100644 index 0000000..50c12f8 --- /dev/null +++ b/Project2/pattern_detector.v @@ -0,0 +1,106 @@ + +// Built and tested with icarus verilog + +module PD( + input clk, + input reset, + input enable, + input [3:0] din, + output pattern1, + output pattern2 +); + + reg _pattern1 = 0, _pattern2 = 0; + + reg [3:0] state = 4'b0000; + + parameter Idle=4'b0000, ZeroPressed=4'b1111, Pat1_05=4'b0001, Pat1_053=4'b0010, + Pat1_0531=4'b0100, Pat2_06=4'b1110, Pat2_061=4'b1101, Pat2_0619=4'b1011; + + // Output based on the current state. Updates outputs immediatley when state changes. + always@(state) + begin + case (state) + Pat1_0531: begin + _pattern1 <= 1; + _pattern2 <= 0; + end + Pat2_0619: begin + _pattern1 <= 0; + _pattern2 <= 1; + end + default: begin + _pattern1 <= 0; + _pattern2 <= 0; + end + endcase + end + + // Set the state based on inputs + always@(posedge clk or posedge reset) + begin + if (reset) + state <= Idle; // Revert to no keys pressed when reset. + if(enable) begin // Only register a new keypress on clock edges and when enabled + case(state) + Idle: + if (din == 0) + state <= ZeroPressed; + ZeroPressed: + if (din == 5) + state <= Pat1_05; + else if (din == 6) + state <= Pat2_06; + else if (din == 0) + state <= ZeroPressed; + else + state <= Idle; + Pat1_05: + if (din == 3) + state <= Pat1_053; + else if (din == 0) + state <= ZeroPressed; + else + state <= Idle; + Pat1_053: + if (din == 1) + state <= Pat1_0531; + else if (din == 0) + state <= ZeroPressed; + else + state <= Idle; + Pat1_0531: // Correct code for pattern 1 + if (din == 0) + state <= ZeroPressed; + else + state <= Idle; + Pat2_06: + if (din == 1) + state <= Pat2_061; + else if (din == 0) + state <= ZeroPressed; + else + state <= Idle; + Pat2_061: + if (din == 9) + state <= Pat2_0619; + else if (din == 0) + state <= ZeroPressed; + else + state <= Idle; + Pat2_0619: // Correct code for pattern 2 + if (din == 0) + state <= ZeroPressed; + else + state <= Idle; + default: + state <= Idle; + endcase + end + end + + // Drive wire outputs with internal registers holding output for state + assign pattern1 = _pattern1; + assign pattern2 = _pattern2; + +endmodule \ No newline at end of file diff --git a/Project3/se.v b/Project3/se.v new file mode 100644 index 0000000..28bbdea --- /dev/null +++ b/Project3/se.v @@ -0,0 +1,109 @@ +// Built and tested with Icarus Verilog + +module SE #( + parameter [7:0] DATAWIDTH = 8, + parameter [7:0] ARRAYLENGTH = 10 +) +( + input clk, + input [(DATAWIDTH * ARRAYLENGTH) - 1 : 0] array_in, + input valid_in, + output [(DATAWIDTH * ARRAYLENGTH) - 1 : 0] array_out, + output valid_out +); + parameter EVEN_ARR_LEN = ARRAYLENGTH % 2 == 0; + + reg [DATAWIDTH - 1: 0] r [0 : ARRAYLENGTH - 1]; // Registers for use between stages + + wire [DATAWIDTH - 1: 0] input_array [0 : ARRAYLENGTH - 1]; // Input represented as array of vectors + wire [DATAWIDTH - 1 : 0] even_cas_out [0 : ARRAYLENGTH - 1]; // compare and swap output 1 array + wire [DATAWIDTH - 1 : 0] odd_cas_out [0 : ARRAYLENGTH - 1]; // compare and swap output 2 array + + reg output_valid = 1'b0; + integer counter = 0; // Handles state of the sorting module + + always@(posedge clk) + begin + if (0 == counter) begin // Stage for when sorter has not been given any valid data. + output_valid <= 0; + if (1 == valid_in) begin + // Clock the inputs if we have valid data. + for (integer i = 0; i < ARRAYLENGTH; i = i + 1) begin + r[i] <= input_array[i]; + end + counter <= 1; // Move to next stage. + end + end + else if (1 == valid_in) begin + counter <= 0; + end + else begin + // Clock the output from even stage at end of each cycle + for (integer i = 0; i < ARRAYLENGTH; i = i + 1) begin + r[i] <= even_cas_out[i]; + end + + // Reset state and indicate that output is valid + if (((ARRAYLENGTH + 1) / 2) == counter) begin + counter <= 0; + output_valid <= 1; + end + else + counter <= counter + 1; // Need more clock cycles to sort + end + end + + // Generate odd stage compare and swap elements + genvar odd; + generate + // Odd length arrays pass first element through odd CAS stage + if (!EVEN_ARR_LEN) assign odd_cas_out[0] = r[0]; + + for (odd = EVEN_ARR_LEN ? 0 : 1; odd < ARRAYLENGTH - 1; odd = odd + 2) begin : g_odd + compare_and_swap #(.SIZE(DATAWIDTH)) u1 (.i1(r[odd]), .i2(r[odd + 1]), + .o1(odd_cas_out[odd]), .o2(odd_cas_out[odd + 1])); + end + endgenerate + + // Generate even stage compare and swap elements + genvar even; + generate + // Even length arrays pass first element through even CAS stage + if (EVEN_ARR_LEN) assign even_cas_out[0] = odd_cas_out[0]; + + // Last element always passed directly through even CAS stage + assign even_cas_out[ARRAYLENGTH - 1] = odd_cas_out[ARRAYLENGTH - 1]; + + for (even = EVEN_ARR_LEN ? 1 : 0; even < ARRAYLENGTH - 2; even = even + 2) + begin : g_even + compare_and_swap #(.SIZE(DATAWIDTH)) u1 (.i1(odd_cas_out[even]), + .i2(odd_cas_out[even + 1]), .o1(even_cas_out[even]), .o2(even_cas_out[even + 1])); + end + endgenerate + + // Get an array of vectors out of the large input vector + genvar i; + generate + for (i = 0; i < ARRAYLENGTH; i = i + 1) + begin : g1 + assign input_array[i] = array_in[(i * DATAWIDTH) + DATAWIDTH - 1 : i * DATAWIDTH]; + assign array_out[(i * DATAWIDTH) + DATAWIDTH - 1 : i * DATAWIDTH] = r[i]; + end + endgenerate + + assign valid_out = output_valid; +endmodule + +// Module to implement compare and swap behaviour +module compare_and_swap #( + parameter [7:0] SIZE = 8 +) +( + input [SIZE - 1 : 0] i1, + input [SIZE - 1 : 0] i2, + output [SIZE - 1: 0] o1, + output [SIZE - 1: 0] o2 +); + assign o1 = i1 > i2 ? i1 : i2; + assign o2 = i1 > i2 ? i2 : i1; +endmodule diff --git a/README.md b/README.md index f4f02e9..8fc2c17 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ # ece-327 -My solutions to projects in my Digital Hardware Systems course. +My solutions to projects in my Digital Hardware Systems course. Written in Verilog. -1. Project 1: Hamming Decoder \ No newline at end of file +1. Project 1: Hamming Decoder +2. Project 2: Pattern detector +3. Project 3: O(n) Sorting