Files
CGA-bench/data/myproject/spi_controller_simple.jsonl

1 line
6.5 KiB
Plaintext
Raw Permalink Normal View History

2026-05-22 10:02:42 +08:00
{"task_id": "spi_controller_simple", "task_number": 1, "description": "Simple SPI master controller with 4-state FSM. Supports CPOL=0, CPHA=0 mode only. On start, latch data_in and shift out MSB-first on mosi while shifting in miso. After 8 bits, output data and return to IDLE.", "header": "module spi_controller_simple (\n input clk,\n input rst_n,\n input [7:0] data_in,\n input start,\n output reg [7:0] data_out,\n output reg busy,\n output reg spi_clk,\n output reg mosi,\n input miso\n);", "module_code": "`timescale 1ns/1ps\n\nmodule spi_controller_simple (\n input clk,\n input rst_n,\n input [7:0] data_in,\n input start,\n output reg [7:0] data_out,\n output reg busy,\n output reg spi_clk,\n output reg mosi,\n input miso\n);\n // Simplified FSM: IDLE -> SEND -> SAMPLE -> DONE -> IDLE\n localparam IDLE = 2'd0;\n localparam SEND = 2'd1;\n localparam SAMPLE = 2'd2;\n localparam DONE = 2'd3;\n\n reg [1:0] state;\n reg [2:0] bit_count;\n reg [7:0] shift_reg;\n reg spi_clk_en;\n\n // SPI clock generation: derived from main FSM state\n // spi_clk toggles when in SEND state\n wire spi_clk_next = spi_clk_en ? ~spi_clk : 1'b0;\n\n always @(posedge clk or negedge rst_n) begin\n if (!rst_n) begin\n spi_clk <= 1'b0;\n end else begin\n spi_clk <= spi_clk_next;\n end\n end\n\n // Main FSM - single always block drives all registers\n always @(posedge clk or negedge rst_n) begin\n if (!rst_n) begin\n state <= IDLE;\n bit_count <= 3'd0;\n shift_reg <= 8'd0;\n data_out <= 8'd0;\n busy <= 1'b0;\n mosi <= 1'b0;\n spi_clk_en <= 1'b0;\n end else begin\n case (state)\n IDLE: begin\n busy <= 1'b0;\n mosi <= 1'b0;\n spi_clk_en <= 1'b0;\n if (start) begin\n busy <= 1'b1;\n shift_reg <= data_in;\n bit_count <= 3'd7;\n state <= SEND;\n spi_clk_en <= 1'b1;\n end\n end\n\n SEND: begin\n busy <= 1'b1;\n mosi <= shift_reg[7];\n // Check if spi_clk just transitioned (rising edge detection)\n if (spi_clk == 1'b0) begin\n state <= SAMPLE;\n end\n end\n\n SAMPLE: begin\n busy <= 1'b1;\n // Shift in miso\n shift_reg <= {shift_reg[6:0], miso};\n if (bit_count == 3'd0) begin\n data_out <= {shift_reg[6:0], miso};\n state <= DONE;\n spi_clk_en <= 1'b0;\n end else begin\n bit_count <= bit_count - 1'b1;\n state <= SEND;\n end\n end\n\n DONE: begin\n busy <= 1'b0;\n mosi <= 1'b0;\n state <= IDLE;\n spi_clk_en <= 1'b0;\n end\n\n default: begin\n state <= IDLE;\n spi_clk_en <= 1'b0;\n end\n endcase\n end\n end\n\nendmodule\n", "testbench": "`timescale 1ns/1ps\n\nmodule tb_spi_controller_simple;\n reg clk;\n reg rst_n;\n reg start;\n reg [7:0] data_in;\n reg miso;\n\n wire [7:0] data_out;\n wire busy;\n wire spi_clk;\n wire mosi;\n\n integer errors;\n integer checks;\n\n localparam IDLE = 2'd0;\n localparam SEND = 2'd1;\n localparam SAMPLE = 2'd2;\n localparam DONE = 2'd3;\n\n spi_controller_simple dut (\n .clk(clk),\n .rst_n(rst_n),\n .data_in(data_in),\n .start(start),\n .data_out(data_out),\n .busy(busy),