implement some of the bus commands for the io_ram module.

This commit is contained in:
Raphael Jacquot 2019-02-06 14:33:44 +01:00
parent 82f4df8e93
commit c77b714777
2 changed files with 35744 additions and 29851 deletions

File diff suppressed because it is too large Load diff

View file

@ -49,15 +49,19 @@ endmodule
*/ */
`define BUSCMD_NOP 0 `define BUSCMD_NOP 0
`define BUSCMD_DP_WRITE 5 `define BUSCMD_DP_WRITE 5
`define BUSCMD_LOAD_DP 7
`define BUSCMD_CONFIGURE 8 `define BUSCMD_CONFIGURE 8
module hp48_io_ram ( module hp48_io_ram (
input clk, input clk,
input reset,
input [19:0] address, input [19:0] address,
input [3:0] command, input [3:0] command,
input [3:0] nibble_in, input [3:0] nibble_in,
output [3:0] nibble_out output [3:0] nibble_out,
output reg io_ram_active,
output reg io_ram_error
); );
localparam IO_RAM_LEN = 64; localparam IO_RAM_LEN = 64;
@ -66,16 +70,34 @@ localparam IO_RAM_LEN = 64;
// localparam BUSCMD_CONFIGURE = C_BUSCMD_CONFIGURE; // localparam BUSCMD_CONFIGURE = C_BUSCMD_CONFIGURE;
reg configured; reg [0:0] configured;
reg [19:0] base_addr; reg [19:0] base_addr;
reg [19:0] data_ptr;
reg [3:0] io_ram [0:IO_RAM_LEN-1]; reg [3:0] io_ram [0:IO_RAM_LEN-1];
/*
*
*
*/
initial initial
begin begin
`ifdef SIM `ifdef SIM
$display("io_ram: unconfigured"); $display("io_ram: set unconfigured");
`endif `endif
configured = 0; configured = 0;
`ifdef SIM
$display("io_ram: reset error flag");
`endif
io_ram_error = 0;
`ifdef SIM
$display("io_ram: setting base address to 0");
`endif
base_addr = 0;
`ifdef SIM
$display("io_ram: setting data pointer to 0");
`endif
data_ptr = 0;
`ifdef SIM `ifdef SIM
$display("io_ram: initializing to 0"); $display("io_ram: initializing to 0");
`endif `endif
@ -88,26 +110,67 @@ initial
end end
`ifdef SIM `ifdef SIM
$display(""); $display("");
$display("io_ram: setting base address to 0");
`endif
base_addr = 0;
`ifdef SIM
$display("io_ram: initialized"); $display("io_ram: initialized");
`endif `endif
end end
always @(posedge clk) /*
*
*
*/
always @(*)
case (command)
`BUSCMD_DP_WRITE:
io_ram_active = ((base_addr >= data_ptr)&(data_ptr < base_addr+IO_RAM_LEN))&(configured);
endcase
always @(negedge clk)
if ((~reset)&(~io_ram_error))
case (command) case (command)
`BUSCMD_NOP: begin end // do nothing `BUSCMD_NOP: begin end // do nothing
`BUSCMD_DP_WRITE:
begin
`ifdef SIM
$write("io_ram: DP_WRITE %5h %h | ", data_ptr, nibble_in);
`endif
// test if write can be done
if (io_ram_active)
begin
io_ram[data_ptr - base_addr] <= nibble_in;
data_ptr <= data_ptr + 1;
`ifdef SIM
$display("OK");
`endif
end
else
`ifdef SIM
$display("NOK - IO_RAM not active (conf: %b)", configured);
`endif
end
`BUSCMD_LOAD_DP:
begin
`ifdef SIM
$display("io_ram: LOAD_DP %5h", address);
`endif
data_ptr <= address;
end
`BUSCMD_CONFIGURE: `BUSCMD_CONFIGURE:
begin begin
`ifdef SIM `ifdef SIM
$display("io_ram: configure at %5h len %d", address, IO_RAM_LEN); $display("io_ram: configure at %5h len %d", address, IO_RAM_LEN);
`endif `endif
base_addr <= address; base_addr <= address;
configured <= 1;
end end
default: default:
begin
`ifdef SIM
$display("io_ram: unhandled command %h", command); $display("io_ram: unhandled command %h", command);
`endif
io_ram_error <= 1;
end
endcase endcase
endmodule endmodule
@ -163,6 +226,7 @@ localparam READ_ROM_CLK = 2;
localparam READ_ROM_STR = 3; localparam READ_ROM_STR = 3;
localparam READ_ROM_VAL = 4; localparam READ_ROM_VAL = 4;
localparam WRITE_STA = 5; localparam WRITE_STA = 5;
localparam WRITE_STROBE = 6;
localparam WRITE_DONE = 8; localparam WRITE_DONE = 8;
localparam RUN_EXEC = 14; localparam RUN_EXEC = 14;
localparam RUN_DECODE = 15; localparam RUN_DECODE = 15;
@ -242,16 +306,15 @@ reg [3:0] runstate;
reg [15:0] decstate; reg [15:0] decstate;
reg [7:0] regdump; reg [7:0] regdump;
// memory access // bus access
//reg rom_clock; reg [19:0] bus_address;
reg [19:0] rom_address;
reg rom_enable;
wire[3:0] rom_nibble;
// io_ram access
reg [3:0] bus_command; reg [3:0] bus_command;
reg [3:0] nibble_in; reg [3:0] nibble_in;
wire [3:0] nibble_out; wire [3:0] nibble_out;
wire io_ram_error;
// should go away, the rom should work like any other bus module
reg rom_enable;
// internal registers // internal registers
reg [3:0] nibble; reg [3:0] nibble;
@ -293,17 +356,19 @@ reg [63:0] R4;
hp_rom calc_rom ( hp_rom calc_rom (
.clk (clk), .clk (clk),
.address (rom_address), .address (bus_address),
.enable (rom_enable), .enable (rom_enable),
.nibble_out (rom_nibble) .nibble_out (nibble_out)
); );
hp48_io_ram io_ram ( hp48_io_ram io_ram (
.clk (clk), .clk (clk),
.address (rom_address), .reset (reset),
.address (bus_address),
.command (bus_command), .command (bus_command),
.nibble_in (nibble_in), .nibble_in (nibble_in),
.nibble_out (nibble_out) .nibble_out (nibble_out),
.io_ram_error (io_ram_error)
); );
/************************************************************************************************** /**************************************************************************************************
* *
@ -366,6 +431,11 @@ begin
if (runstate == RUN_START) if (runstate == RUN_START)
runstate <= READ_ROM_STA; runstate <= READ_ROM_STA;
if (io_ram_error)
begin
halt <= 1;
end
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
// //
// REGISTER UTILITIES // REGISTER UTILITIES
@ -399,7 +469,7 @@ begin
begin begin
//$display("READ_ROM_STA"); //$display("READ_ROM_STA");
rom_enable <= 1'b1; rom_enable <= 1'b1;
rom_address <= PC; bus_address <= PC;
runstate <= READ_ROM_CLK; runstate <= READ_ROM_CLK;
end end
@ -415,8 +485,8 @@ begin
if (runstate == READ_ROM_STR) if (runstate == READ_ROM_STR)
begin begin
//$display("READ_ROM_STR"); //$display("READ_ROM_STR");
nibble <= rom_nibble; nibble <= nibble_out;
//$display("PC: %h | read => %h", PC, rom_nibble); //$display("PC: %h | read => %h", PC, nibble_out);
PC <= PC + 1; PC <= PC + 1;
rom_enable <= 1'b0; rom_enable <= 1'b0;
// rom_clock <= 1'b0; // rom_clock <= 1'b0;
@ -583,14 +653,14 @@ begin
* ---------- field ----------- * ---------- field -----------
* A B fs d * A B fs d
* ---------------------------- * ----------------------------
* 140 148 150a 158x DAT0=A field * 140 148 150a 158x DAT0=A field 0000 1000
* 141 149 151a 159x DAT1=A field * 141 149 151a 159x DAT1=A field 0001 1001
* 142 14A 152a 15Ax A=DAT0 field * 142 14A 152a 15Ax A=DAT0 field 0010 1010
* 143 14B 153a 15Bx A=DAT1 field * 143 14B 153a 15Bx A=DAT1 field 0011 1011
* 144 14C 154a 15Cx DAT0=C field * 144 14C 154a 15Cx DAT0=C field 0100 1100
* 145 14D 155a 15Dx DAT1=C field * 145 14D 155a 15Dx DAT1=C field 0101 1101
* 146 14E 156a 15Ex C=DAT0 field * 146 14E 156a 15Ex C=DAT0 field 0110 1110
* 147 14F 157a 15Fx C=DAT1 field * 147 14F 157a 15Fx C=DAT1 field 0111 1111
* *
* fs: P WP XS X S M B W * fs: P WP XS X S M B W
* a: 0 1 2 3 4 5 6 7 * a: 0 1 2 3 4 5 6 7
@ -671,7 +741,41 @@ begin
endcase endcase
`endif `endif
end end
WRITE_STA:
begin
`ifdef SIM
$display("WRITE_STA | ptr %s | dir %s | reg %s | field %h | off %h | ctr %h | cnt %h",
t_ptr?"D1":"D0", t_dir?"IN":"OUT", t_reg?"C":"A", t_field, t_field, t_offset, t_ctr, t_cnt);
`endif
bus_command <= `BUSCMD_LOAD_DP;
bus_address <= (~t_ptr)?D0:D1;
runstate <= WRITE_STROBE;
end
WRITE_STROBE:
begin
`ifdef SIM
$display("WRITE_STROBE | ptr %s | dir %s | reg %s | field %h | off %h | ctr %h | cnt %h",
t_ptr?"D1":"D0", t_dir?"IN":"OUT", t_reg?"C":"A", t_field, t_offset, t_ctr, t_cnt);
`endif
bus_command <= `BUSCMD_DP_WRITE;
nibble_in <= (~t_reg)?A[t_offset*4+:4]:C[t_offset*4+:4];
t_offset <= t_offset + 1;
t_ctr <= t_ctr + 1;
if (t_ctr == t_cnt)
begin
runstate <= WRITE_DONE;
end
end
WRITE_DONE:
begin
`ifdef SIM
$display("WRITE_DONE | ptr %s | dir %s | reg %s | field %h | off %h | ctr %h | cnt %h",
t_ptr?"D1":"D0", t_dir?"IN":"OUT", t_reg?"C":"A", t_field, t_offset, t_ctr, t_cnt);
`endif
bus_command <= `BUSCMD_NOP;
runstate <= RUN_START;
decstate <= DECODE_START;
end
default: default:
begin begin
`ifdef SIM `ifdef SIM