Files
ece-327/Project4/mst.v
2025-12-14 12:40:05 -05:00

168 lines
5.3 KiB
Verilog

// Designed and tested with icarus verilog
module mst
(
input clock,
input reset,
input enable,
output reg [7:0] wra,
output reg [7:0] wrd,
output reg [7:0] rda,
output reg [7:0] rdd,
output reg we,
output reg [8:0] t1attempts,
output reg [8:0] t1fails,
output reg [8:0] t2attempts,
output reg [8:0] t2fails,
output reg done
);
wire [7:0] rddmem;
memory u2 (.clock(clock), .reset(reset), .we(we), .wra(wra), .wrd(wrd), .rda(rda), .rdd(rddmem));
parameter NUM_BYTES = 256;
parameter T1Write = 3'b001, T1Read = 3'b010, T1Verify = 3'b011, T2Write = 3'b100, T2Read = 3'b101, T2Verify = 3'b110, Done = 3'b111;
// T1___ corresponds to test 1 (writing zeros), T2___ corresponds to test 2 (writing FF).
reg [2:0] state = T1Write;
// State machine outputs
always@(negedge clock)
begin
rdd <= rddmem; // Update the memory read value every cycle
case (state)
T1Write: begin // Test 1 Write phase
done <= 0;
wrd <= 8'h00; // Test 1: write hex 00.
we <= enable == 1 ? 1 : 0; // Moore machine, this state is also used as idle state
wra <= t1attempts; // Address we care about can be indexed by test#.
rda <= t1attempts;
end
T1Read: begin // Test 1 Read phase
done <= 0;
wrd <= 8'h00;
we <= 0; // Begin read phase by setting write enable to 0.
wra <= t1attempts;
rda <= t1attempts;
end
T1Verify: begin // Test 1 Verify phase
done <= 0;
wrd <= 8'h00;
we <= 0;
wra <= t1attempts;
rda <= t1attempts;
if (enable && rddmem != 8'h00)
t1fails <= t1fails + 1; // Fail the attempt if we read the wrong value.
end
T2Write: begin // Test 2 Write phase
done <= 0;
wrd <= 8'hFF; // Test 2: write hex FF.
we <= 1;
wra <= t2attempts;
rda <= t2attempts;
end
T2Read: begin // Test 2 Read phase
done <= 0;
wrd <= 8'hFF;
we <= 0;
wra <= t2attempts;
rda <= t2attempts;
end
T2Verify: begin // Test 2 Verify phase
done <= 0;
wrd <= 8'hFF;
we <= 0;
wra <= t2attempts;
rda <= t2attempts;
if (enable && rddmem != 8'hFF)
t2fails <= t2fails + 1; // Fail the attempt if we read the wrong value.
end
default: begin // Done state
done <= 1;
end
endcase
end
// State transitions
always@(negedge clock)
begin
if (reset) begin // Handle synchronous reset signal
state <= T1Write; // Idle state is handled by T1Write state.
t1attempts <= 0;
t2attempts <= 0;
t1fails <= 0;
t2fails <= 0;
we <= 0;
done <= 0;
wrd <= 0;
rda <= 0;
wra <= 0;
end
else if (enable)
case (state) // State transitions
T1Write: begin
state <= T1Read;
end
T1Read: begin
state <= T1Verify;
end
T1Verify: begin
t1attempts <= t1attempts + 1;
if (t1attempts >= NUM_BYTES - 1)
state <= T2Write; // Transition to test 2 if we are done with test 1.
else
state <= T1Write;
end
T2Write: begin
state <= T2Read;
end
T2Read: begin
state <= T2Verify;
end
T2Verify: begin
t2attempts <= t2attempts + 1;
if (t2attempts >= NUM_BYTES - 1)
state <= Done; // Transition to done if we are done with test 2.
else
state <= T2Write;
end
default: begin
state <= Done;
end
endcase
end
endmodule
module memory(
input clock,
input reset,
input we,
input [7:0] wra,
input [7:0] wrd,
input [7:0] rda,
output [7:0] rdd
);
reg [7:0] mem[255:0];
reg [7:0] rddata;
always @(posedge clock)
begin
if(reset)
begin
rddata <= 8'h00;
end
else
begin
if(we)
begin
mem[wra] <= wrd;
end
rddata <= mem[rda];
end
end
assign rdd = rddata;
endmodule